?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Accounting and Validation: Validation Interfaces' ??
MODULE avm$validation_interfaces;

{ PURPOSE:
{   This module contains external interfaces used to manage a validation file.  It contains interfaces to
{   create, update and read validation information for users, accounts, and projects.

{ DESIGN:
{   The interfaces in this module protect the information in a validation file from update or retrieval by
{   unprivileged users.
{
{   The interfaces in this module are grouped into the following catagories.
{
{   General Purpose Interfaces
{   Interfaces to create validation records
{   Interfaces to read validation records
{   Interfaces to change validation records
{   Interfaces to delete validation records
{   Interfaces to verify validation records exist
{
{   Interfaces to create field descriptions
{   Interfaces to read field descriptions
{   Interfaces to change field descriptions
{   Interfaces to change field names, delete fields, and restore fields.
{
{   Interfaces to change field values
{   Interfaces to read field display values
{   Interfaces to read field values for the current executing job
{
{   Helper procedures
{
*copyc avc$compile_test_code
*copyc dft$procedure_address_ordinal
?? NEWTITLE := 'Global Declarations referenced by this module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ame$condition_codes
*copyc avc$accounting_statistics
*copyc avc$system_defined_limit_names
*copyc avc$validation_default_values
*copyc avc$validation_field_names
*copyc avc$validation_file_name
*copyc avc$validation_file_version
*copyc avc$validation_level_const_name
*copyc avc$validation_level_names
*copyc avc$validation_record_names
*copyc ave$admin_validations_errors
*copyc ave$template_file_mgr_errors
*copyc ave$validation_interface_errors
*copyc avt$conditional_capabilities
*copyc avt$field_utility_information
*copyc avt$file_utility_information
*copyc avt$validation_file_type
*copyc avt$job_limit_information
*copyc avt$total_limit_information
*copyc avt$total_limit_update_record
*copyc avt$record_utility_info_entry
*copyc avt$record_utility_info_header
*copyc avt$validation_record_info
*copyc avt$validated_limit
*copyc avt$validation_authority
*copyc avt$validation_items
*copyc avt$validation_key
*copyc avt$validation_level
*copyc avt$validation_record
*copyc clc$standard_file_names
*copyc cle$ecc_miscellaneous
*copyc cle$ecc_messages_and_prompts
*copyc cle$ecc_utilities
*copyc clt$block
*copyc clt$utility_name
*copyc i#current_sequence_position
*copyc i#move
*copyc jmc$system_family
*copyc jme$input_is_initiated
*copyc jme$no_jobs_were_found
*copyc jme$queued_file_conditions
*copyc jmt$job_class
*copyc ofe$error_codes
*copyc ost$caller_identifier
*copyc ost$status
*copyc pme$system_time_exceptions
*copyc sfc$unlimited

   TYPE
     avt$server_prevalidate_job_in = record
       validation_level: avt$validation_level,
       user_name: ost$user_name,
       family_name: ost$family_name,
       number_of_val_attributes: integer,
       number_of_def_attributes: integer,
     recend;

?? POP ??
PROCEDURE [INLINE] dummy;

{  Prevent XREF for avp$capability_active from interfering with
{  the procedure that is defined in this module.
{
{  The avp$system_administrator and avp$family_administrator decks
{  contain '*copyc avp$capability_active'.
*copyc avp$capability_active

PROCEND dummy;
*copyc avp$change_desc_utility_info
*copyc avp$change_field
*copyc avp$change_field_name
*copyc avp$change_file_utility_info
*copyc avp$close_template_file
*copyc avp$create_data_record
*copyc avp$create_description_record
*copyc avp$create_field
*copyc avp$delete_data_record
*copyc avp$delete_data_records
*copyc avp$delete_field
*copyc avp$determine_if_key_exists
*copyc avp$check_for_console_operation
*copyc avp$encrypt_password
*copyc avp$family_administrator
*copyc avp$get_desc_utility_info
*copyc avp$get_desc_utility_info_size
*copyc avp$get_description_record
*copyc avp$get_field
*copyc avp$get_field_description
*copyc avp$get_field_names
*copyc avp$get_file_utility_info
*copyc avp$old_encrypt_password
*copyc avp$open_template_file
*copyc avp$process_password_attributes
*copyc avp$read_data_record
*copyc avp$read_next_data_record
*copyc avp$restore_field
*copyc avp$restructure_template_file
*copyc avp$rewrite_data_record
*copyc avp$security_option_active
*copyc avp$store_validation_info
*copyc avp$system_administrator
*copyc avp$unlock_template_file
*copyc avp$verify_type_conformance
*copyc avv$debug_accounting_validation
*copyc avv$job_pageable_val_info
*copyc avv$security_options
*copyc avv$validation_level
*copyc clp$convert_date_time_to_string
*copyc clp$convert_file_ref_to_string
*copyc clp$convert_integer_to_rjstring
*copyc clp$convert_integer_to_string
*copyc clp$delete_file_from_cmnd_list
*copyc clp$evaluate_file_reference
*copyc clp$find_current_block
*copyc clp$find_task_block
*copyc clp$find_utility_block
*copyc clp$validate_name
*copyc clp$get_path_description
*copyc clp$get_path_name
*copyc clp$get_processing_phase
*copyc clp$trimmed_string_size
*copyc dfp$check_job_recovery
*copyc dfp$locate_served_family
*copyc dfp$send_remote_procedure_call
*copyc fsp$path_element
*copyc ifp$get_terminal_attributes
*copyc jmp$change_input_attributes
*copyc jmp$get_job_status
*copyc jmp$get_result_size
*copyc jmp$system_job
*copyc mmp$create_scratch_segment
*copyc mmp$delete_scratch_segment
*copyc osp$append_status_parameter
*copyc osp$check_for_desired_mf_class
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$generate_log_message
*copyc osp$generate_output_message
*copyc osp$get_set_name
*copyc osp$set_status_abnormal
*copyc osp$set_status_from_condition
*copyc oss$job_paged_literal
*copyc osp$set_status_condition
*copyc osp$verify_system_privilege
*copyc oss$task_private
*copyc oss$task_shared
*copyc ost$heap
*copyc pfp$permit
*copyc pfp$purge_catalog_contents
*copyc pfp$purge_master_catalog
*copyc pfp$reset_administrator_status
*copyc pfp$set_family_administrator
*copyc pfp$utility_attach
*copyc pmp$compute_date_time
*copyc pmp$compute_date_time_increment
*copyc pmp$get_compact_date_time
*copyc pmp$get_default_date_time_form
*copyc pmp$get_job_mode
*copyc pmp$get_unique_name
*copyc pmp$get_user_identification
*copyc rmp$request_mass_storage
*copyc sfp$convert_stat_code_to_name
*copyc sfp$emit_audit_statistic
*copyc sfp$emit_statistic
*copyc sfp$get_job_limit
*copyc syp$store_system_constant
*copyc osv$upper_to_lower
  ?IF avc$compile_test_code THEN

    VAR
      osv$job_pageable_heap: [XDCL] ^ost$heap := NIL;

    VAR
      osv$task_shared_heap: [XDCL] ^ost$heap := NIL;

    VAR
      osv$task_private_heap: [XDCL] ^ost$heap := NIL;

  ?ELSE
*copyc osv$task_shared_heap
*copyc osv$task_private_heap
  ?IFEND
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations declared by this module', EJECT ??

{ Variables used to hold static login validation information for a job

  VAR
    avv$account_name: [XDCL, oss$task_shared] avt$account_name := osc$null_name,
    avv$minimum_ring: [STATIC, oss$task_shared] ost$ring := osc$user_ring,
    avv$nominal_ring: [STATIC, oss$task_shared] ost$ring := osc$user_ring,
    avv$project_name: [XDCL, oss$task_shared] avt$project_name := osc$null_name,
    avv$validated_limits: [XDCL, #GATE, oss$task_shared] ^avt$validated_limit := NIL,
    avv$validation_record_info: [STATIC, oss$task_private] ^avt$validation_record_info := NIL;

{ Variable used to indicate which system_operator_utility capabilities are
{ active in the job synchronous task of the system job.  This information is used
{ to condition the content of (refreshing) displays written to window A or window B.

  VAR
    avv$active_sou_capabilities: [XDCL, oss$task_shared] avt$conditional_capabilities
      := -$avt$conditional_capabilities[];

{ Variable used to indicate which system_operator_utility capabilities the system
{ job is validated for.  This information is used to determine what conditions
{ should cause an alarm indication to be presented at the system console.

  VAR
    avv$validated_sou_capabilities: [XDCL, oss$task_shared] avt$conditional_capabilities
      := -$avt$conditional_capabilities[];

{ Variable used to indicate whether the begin_production_environment command
{ has been executed.  This variable is used only by the system job.

  VAR
    avv$production_environ_begun: [XDCL, oss$task_shared] boolean := FALSE;

{ Names of conditional capability validation fields.

  VAR
    avv$cond_capability_names: [XDCL, READ, oss$job_paged_literal] array [avt$conditional_capability] of
          ost$name := [avc$accounting_administration, avc$configuration_admin, avc$family_administration,
          avc$removable_media_admin, avc$removable_media_operation, avc$system_administration,
          avc$system_displays, avc$system_operation];

?? TITLE := '  avp$activate_capabilities', EJECT ??
{
{ PURPOSE:
{
{   This interface is used to activate one or more conditional capabilities.
{ Activating a conditional capability allows the functions validated by the
{ capability to be performed.
{
{ DESIGN:
{
{   The system job is always permited to activate the system_administration
{ capability.  In all other cases, the login user of the executing job must be
{ validated for each capability to be activated.
{
{   The set of active conditional capabilities is stored on the block stack.
{ The active capabilities are either stored in the current block stack entry or
{ in the block stack entry of a specified utility and all child blocks, depending
{ on the value of the utility parameter.
{
{ NOTE:
{   If system_administration or family_administration is activated in a block
{ associated with tasks other than the executing task, then the
{ privileges associated with these capabilities will NOT be in effect unless
{ the PF subsystem re-evaluates its (task private) administrator status within
{ those tasks.
{

  PROCEDURE [XDCL, #GATE] avp$activate_capabilities (
         capabilities: avt$conditional_capabilities;
         utility: clt$utility_name;
    VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      block: ^clt$block,
      block_in_current_task: boolean,
      capability: boolean,
      conditional_capability: avt$conditional_capability,
      current_block: ^clt$block,
      name_is_valid: boolean,
      restricted_mainframe: boolean,
      user_id: ost$user_identification,
      utility_block: ^clt$block,
      validated_utility_name: ost$name;

    status.normal := TRUE;

  /activate_capabilities/
    BEGIN

{ Verify that the console operation only security option is enforced if on.

    avp$check_for_console_operation ('Conditional capabilities', status);
    IF NOT status.normal THEN
      EXIT /activate_capabilities/;
    IFEND;

    { Check for system_administration validation.  If this is the system job, we don't
    { need to check the validation unless we are running on a Soviet or China system.

    osp$check_for_desired_mf_class (osc$mc_china_or_soviet_class, restricted_mainframe);

    IF ( (avc$cc_system_admin IN capabilities) AND (NOT (jmp$system_job ()) OR
          (restricted_mainframe))) THEN
      avp$get_capability (avc$system_administration, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability, 'system_administration', status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Check for family_administration validation.

    IF (avc$cc_family_admin IN capabilities) THEN
      avp$get_capability (avc$family_administration, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability, 'family_administration', status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Check for accounting_administration validation.

    IF (avc$cc_accounting_admin IN capabilities) THEN
      avp$get_capability (avc$accounting_administration, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability, 'accounting_administration', status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Check for configuration_administration validation.

    IF (avc$cc_configuration_admin IN capabilities) THEN
      avp$get_capability (avc$configuration_admin, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability,
            'configuration_administration', status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Check for removable_media_administration validation.

    IF (avc$cc_removable_media_admin IN capabilities) THEN
      avp$get_capability (avc$removable_media_admin, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability, 'removable_media_administration',
              status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Check for removable_media_operation validation.

    IF (avc$cc_removable_media_operator IN capabilities) THEN
      avp$get_capability (avc$removable_media_operation, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability, 'removable_media_operation', status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Check for system_displays validation.

    IF (avc$cc_system_displays IN capabilities) THEN
      avp$get_capability (avc$system_displays, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability, 'system_displays', status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Check for system_operation validation.

    IF (avc$cc_system_operator IN capabilities) THEN
      avp$get_capability (avc$system_operation, avc$user, capability, status);
      IF NOT status.normal THEN
        EXIT /activate_capabilities/;
      ELSEIF NOT capability THEN
        osp$set_status_abnormal ('AV', ave$missing_required_capability, 'system_operation', status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ Activate capabilities in appropriate blocks.

    clp$find_current_block (current_block);

    IF (utility = osc$null_name) THEN
      current_block^.active_capabilities :=  current_block^.active_capabilities + capabilities;
      validated_utility_name := osc$null_name;
    ELSE
      clp$validate_name (utility, validated_utility_name, name_is_valid);
      IF NOT name_is_valid THEN
        osp$set_status_abnormal ('CL', cle$improper_utility_name,  utility, status);
        EXIT /activate_capabilities/;
      IFEND;
      clp$find_utility_block (validated_utility_name, utility_block, block_in_current_task);
      IF utility_block <> NIL THEN
        utility_block^.active_capabilities := utility_block^.active_capabilities + capabilities;
        WHILE current_block <> utility_block DO
          current_block^.active_capabilities := current_block^.active_capabilities + capabilities;
          current_block := current_block^.previous_block;
        WHILEND;
      ELSE
        osp$set_status_abnormal ('CL', cle$unknown_utility, validated_utility_name, status);
        EXIT /activate_capabilities/;
      IFEND;
    IFEND;

{ If system_administration or family_administration has been activated, then
{ re-evaluate the PF subsystem's administrator status for the executing task.

    IF (avc$cc_system_admin IN capabilities) OR (avc$cc_family_admin  IN capabilities) THEN
      pfp$reset_administrator_status;
    IFEND;


{ If activating capabilities for the System Operator Utility in the system job
{ and the executing task is the job synchronous task, then "push" the activated
{ capabilities into avv$active_sou_capabilities.  The "old" avv$active_sou_capabilities
{ value is saved in the SOU utility block and will be restored when the block is popped
{ off the block stack.

    IF jmp$system_job () AND (validated_utility_name = 'SYSTEM_OPERATOR_UTILITY') THEN
      clp$find_task_block (block, status);
      IF block^.synchronous_with_job THEN
        utility_block^.active_sou_capabilities.saved := TRUE;
        utility_block^.active_sou_capabilities.value := avv$active_sou_capabilities;
        avv$active_sou_capabilities := utility_block^.active_capabilities;
      IFEND;
    IFEND;
    END /activate_capabilities/;

{ Emit audit statistics for activated capabilities.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_activate_capability;
      FOR conditional_capability := LOWERVALUE (conditional_capability) TO
            UPPERVALUE (conditional_capability) DO
        IF conditional_capability IN capabilities THEN
          audit_information.activate_capability.field_name_p :=
                ^avv$cond_capability_names [conditional_capability];
          sfp$emit_audit_statistic (audit_information, status);
        IFEND;
      FOREND;
    IFEND;

  PROCEND avp$activate_capabilities;
?? TITLE := '  avp$begin_production_environ', EJECT ??
{
{ PURPOSE:
{
{   This interface is used to record the completion of the deadstart process in
{ the system job.  At the completion of deadstart, the active_capabilities field
{ is cleared in all blocks preceding the current block on the block stack,
{ except the job monitor task block which retains all capabilities.
{

  PROCEDURE [XDCL, #GATE] avp$begin_production_environ
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
      file: clt$command_list_entry_file,
      file_name: [READ, oss$job_paged_literal] string (23) := '$system.osf$sou_library';

    status.normal := TRUE;
    IF NOT jmp$system_job () THEN
      osp$set_status_abnormal ('JM', jme$must_be_system_job, 'avp$begin_production_environ', status);
      RETURN;
    IFEND;

    IF avv$production_environ_begun THEN
      RETURN;
    IFEND;

    clp$find_current_block (block);

    WHILE block <> NIL DO
      IF NOT ((block^.kind=clc$task_block) AND (block^.task_kind=clc$job_monitor_task)) THEN
        block^.active_capabilities := $avt$conditional_capabilities [];
      IFEND;
      block := block^.previous_block;
    WHILEND;

{ Delete $system.osf$sou_library from the system job command list.  The commands
{ in this library must now be accessed through the SYSTEM_OPERATOR_UTILITY.

    file.kind := clc$command_list_entry_path;
    file.path := ^file_name;
    clp$delete_file_from_cmnd_list (file, {ignore} status);
    status.normal := TRUE;

    avv$production_environ_begun := TRUE;

    avv$active_sou_capabilities := $avt$conditional_capabilities [];

  PROCEND avp$begin_production_environ;
?? TITLE := '    avp$change_password', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used by the change login password SCL command to change the value of the login password
{   on the validation file for a user.

  PROCEDURE [XDCL, #GATE] avp$change_password
    (    old_password: avt$password;
         new_password: avt$password;
         expiration_date: ^ost$date_time;
         expiration_interval: ^pmt$time_increment;
         update_batch_job_passwords: boolean;
     VAR status: ost$status);

    VAR
      command_table_size: integer,
      default_value: avt$field_value,
      descriptive_text: ^avt$descriptive_text,
      field_utility_info_ptr: ^avt$field_utility_information,
      ignore_status: ost$status,
      login_password: ^avt$login_password,
      record_id: ost$name,
      served_family: boolean,
      type_specification: avt$type_specification,
      user_identification: ost$user_identification,
      utility_information: ^avt$utility_information,
      validation_file_information: avt$template_file_information,
      validation_record_info: ^avt$validation_record_info;

?? NEWTITLE := '      change_pw_condition_handler', EJECT ??
{ PURPOSE:
{   This is a block exit condition handler to ensure that the validation file is closed on an abnormal exit
{   from the change password interface.

    PROCEDURE change_pw_condition_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      handler_status.normal := TRUE;

      avp$end_subutility_session (record_id, FALSE, validation_file_information, ignore_status);
      avp$close_validation_file (validation_file_information, ignore_status);

    PROCEND change_pw_condition_handler;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

{ Get executing user identification.

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

{ Don't allow a password change on the client.

    avp$check_for_served_family (user_identification.family, served_family);
    IF served_family THEN
      osp$set_status_abnormal ('AV', ave$not_allowed_on_client, 'CHANGE_PASSWORD', status);
      RETURN;
    IFEND;

{ Open the validation file for the executing family.

    avp$open_system_validation_file (user_identification.family, validation_file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    osp$establish_block_exit_hndlr (^change_pw_condition_handler);

  /change/
    BEGIN

{ Begin change user utility session.

      avp$change_user_record (user_identification.user, record_id, command_table_size,
            validation_file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Find the information for this subutility session within the validation record information chain.

      find_validation_record_info (record_id, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ This interface is only used to change the users own password so always set the authority to user.

      validation_record_info^.caller_authority := avc$user_authority;

{ Change the login password value using the input information.

      PUSH login_password;
      login_password^.encrypted := FALSE;
      login_password^.value := new_password;
      avp$change_login_password_value (avc$login_password, ^old_password, login_password, expiration_date,
            expiration_interval, NIL, NIL, NIL, NIL, NIL, record_id, update_batch_job_passwords,
            validation_file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ End the change user utility session.

      avp$end_subutility_session (record_id, TRUE, validation_file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      avp$close_validation_file (validation_file_information, status);
    END /change/;
    IF NOT status.normal THEN

{ NOTE: If the subutility session has already been ended this call will do nothing.

      avp$end_subutility_session (record_id, FALSE, validation_file_information, ignore_status);
      avp$close_validation_file (validation_file_information, ignore_status);
    IFEND;

    osp$disestablish_cond_handler;

  PROCEND avp$change_password;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] avp$change_user_pf_space_limit', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of the permanent file space limit accumulator
{   on the validation file for a user.

  PROCEDURE [XDCL, #GATE] avp$change_user_pf_space_limit
    (    family_name: ost$family_name;
         total_accumulation: ^avt$limit_value;
     VAR user_name: ost$user_name;
     VAR status: ost$status);

    VAR
      ignore_status: ost$status,
      number_of_command_entries: integer,
      record_id: ost$name,
      validation_file_information: avt$template_file_information;

?? NEWTITLE := 'change_pfsl_condition_handler', EJECT ??
{ PURPOSE:
{   This is a block exit condition handler to ensure that the validation file is closed on an
{   abnormal exit.

    PROCEDURE change_pfsl_condition_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        ignore_status: ost$status;

      avp$end_subutility_session (record_id, FALSE, validation_file_information, ignore_status);
      avp$close_validation_file (validation_file_information, ignore_status);

    PROCEND change_pfsl_condition_handler;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

{ Validate that we were called from within the system.

    osp$verify_system_privilege;

{ Open the validation file for the executing family.

    avp$open_system_validation_file (family_name, validation_file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    osp$establish_block_exit_hndlr (^change_pfsl_condition_handler);

{ Begin change user utility session.

    avp$change_user_record (user_name, record_id, number_of_command_entries,
          validation_file_information, status);
    IF NOT status.normal THEN
      avp$end_subutility_session (record_id, FALSE, validation_file_information, ignore_status);
      avp$close_validation_file (validation_file_information, ignore_status);
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

{ Change the permanent_file_space_limit accumulator.

    avp$change_accum_limit_value (avc$permanent_file_space_limit, NIL, NIL, NIL, total_accumulation,
          record_id, validation_file_information, status);
    IF NOT status.normal THEN
      avp$end_subutility_session (record_id, FALSE, validation_file_information, ignore_status);
      avp$close_validation_file (validation_file_information, ignore_status);
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

{ End the change user utility session.

    avp$end_subutility_session (record_id, TRUE, validation_file_information, status);
    IF NOT status.normal THEN
      avp$close_validation_file (validation_file_information, ignore_status);
      osp$disestablish_cond_handler;
      RETURN;
    IFEND;

    avp$close_validation_file (validation_file_information, status);

    osp$disestablish_cond_handler;

  PROCEND avp$change_user_pf_space_limit;
?? TITLE := '    avp$check_for_served_family', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interfaces is used to determine if a family is served by another mainframe.

  PROCEDURE [XDCL, #GATE] avp$check_for_served_family
    (    family_name: string (* <= osc$max_name_size);
     VAR served_family: boolean);

     VAR
       local_family_name: ost$name,
       p_queue_interface_table: dft$p_queue_interface_table,
       queue_index: dft$queue_index,
       served_family_table_index: dft$served_family_table_index,
       server_mainframe_id: pmt$binary_mainframe_id,
       server_state: dft$server_state;

    local_family_name := family_name;
    ?IF NOT avc$compile_test_code THEN
      dfp$locate_served_family (local_family_name, served_family, served_family_table_index,
            server_mainframe_id, p_queue_interface_table,
            queue_index, server_state);
    ?ELSE
      served_family := FALSE;
    ?IFEND

  PROCEND avp$check_for_served_family;
?? TITLE := '[XDCL, #GATE] avp$clear_active_capabilities', EJECT ??

{ PURPOSE:
{   The purpose of this request is to deactivate all conditional capabilities
{   that are active for the current block in the block stack.

  PROCEDURE [XDCL, #GATE] avp$clear_active_capabilities
    (VAR status: ost$status);

    VAR
      current_block: ^clt$block;

    status.normal := TRUE;
    IF NOT jmp$system_job () THEN
      osp$set_status_abnormal ('JM', jme$must_be_system_job, 'avp$clear_active_capabilities', status);
      RETURN;
    IFEND;

    clp$find_current_block (current_block);
    current_block^.active_capabilities := $avt$conditional_capabilities [];

{ Re-evaluate the PF subsystem's administrator status for the executing task.

    pfp$reset_administrator_status;

  PROCEND avp$clear_active_capabilities;
?? TITLE := '    avp$close_validation_file', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interfaces is used to close a validation file.
{
{ NOTES:
{   The file utility information NEW_FILE field is updated to contain the value FALSE each time a validation
{   file is closed.
{
{   The NEW_FILE field is used to allow or disallow specification of encrypted passwords as input to a login
{   password update.  Encrypted passwords as input are allowed only on recreation from source.  (i.e.  When
{   recreating a validation file from source a new validation file is opened and the NEW_FILE field is TRUE so
{   encrypted passwords are accepted.  As soon as that validation file is closed encrypted passwords will no
{   longer be accepted.)

  PROCEDURE [XDCL, #GATE] avp$close_validation_file
    (VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      file_utility_information: ^avt$file_utility_information,
      ignore_status: ost$status,
      utility_information: ^avt$utility_information;

    status.normal := TRUE;

  /close_validation_file/
    BEGIN

{ Get the current file utility information.

      PUSH utility_information: [[REP 1 OF avt$file_utility_information]];
      RESET utility_information;
      avp$get_file_utility_info (utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /close_validation_file/;
      IFEND;
      RESET utility_information;
      NEXT file_utility_information IN utility_information;
      IF file_utility_information = NIL THEN
        corrupted_sequence ('AVP$CLOSE_VALIDATION_FILE', 'NEW_FILE', 'FILE_UTILITY_INFORMATION', status);
        EXIT /close_validation_file/;
      IFEND;

{ Assign the new_file field a FALSE value

      IF file_utility_information^.new_file THEN
        file_utility_information^.new_file := FALSE;
        avp$change_file_utility_info (#SEQ (file_utility_information^), file_information, status);
      IFEND;
    END /close_validation_file/;

{ Close the validation file.

    IF status.normal THEN
      avp$close_template_file (file_information, status);
    ELSE
      avp$close_template_file (file_information, ignore_status);
    IFEND;

  PROCEND avp$close_validation_file;
?? TITLE := '    avp$display_pw_exp_warning', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is called at login to display a warning message stating when the user's password will
{   expire.

  PROCEDURE [XDCL, #GATE] avp$display_pw_exp_warning
    (VAR status: ost$status);

    VAR
      change_date: ost$date_time,
      current_date_time: ost$date_time,
      date_format: ost$default_date_format,
      date_time: ost$date_time,
      date_time_to_format: clt$date_time,
      date_string: ost$string,
      increment: pmt$time_increment,
      job_mode: jmt$job_mode,
      login_password_attributes: array [1..1] of ost$name,
      login_password_exp_date: ost$date_time,
      login_password_exp_interval: pmt$time_increment,
      login_password_max_exp_interval: pmt$time_increment,
      login_password_exp_warning: pmt$time_increment,
      login_password_exp_chg_interval: pmt$time_increment,
      message_status: ost$status,
      number_of_login_password_attrib: avt$name_list_size,
      time_format: ost$default_time_format,
      time_string: ost$string;

    status.normal := TRUE;

{ Get the login password value for the current executing user.

    avp$get_login_password_value (avc$login_password, avc$user, login_password_exp_date,
          login_password_exp_interval, login_password_max_exp_interval, login_password_exp_warning,
          login_password_exp_chg_interval, change_date, login_password_attributes,
          number_of_login_password_attrib, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF login_password_exp_date.year <> avc$no_expiration_date THEN

{ If the password has an expiration date.

      IF login_password_exp_warning.day <> avc$unlimited_exp_interval THEN

{ If the expiration warning interval is not unlimited (always display) then calculate to determine the date
{ and time that expiration warning should start.

{ Get the current date and time.

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

{ The date and time that expiration warning should start is determined by subtracting the expiration warning
{ interval from the expiration date.
{ NOTE:  The expiration warning interval is stored as a negative date time increment.

        pmp$compute_date_time (login_password_exp_date, login_password_exp_warning, date_time, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ The time difference between the current date time and the date time to start displaying the exipration
{ warning is calculated.

        pmp$compute_date_time_increment (current_date_time, date_time, increment, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

{ If the expiration warning interval is unlimited (always display) OR it is at or past the date time to start
{ displaying the warning message (i.e.  the time difference calculated above is negative) then display the
{ message.

      IF ((login_password_exp_warning.day = avc$unlimited_exp_interval)) OR
            ((increment.year < 0) OR (increment.month < 0) OR (increment.day < 0) OR (increment.hour < 0) OR
            (increment.minute < 0) OR (increment.second < 0) OR (increment.millisecond < 0)) THEN
        osp$set_status_abnormal ('CL', cle$password_expiration_warning, '', message_status);
        pmp$get_default_date_time_form (date_format, time_format);
        date_time_to_format.value := login_password_exp_date;
        date_time_to_format.date_specified := TRUE;
        date_time_to_format.time_specified := TRUE;
        clp$convert_date_time_to_string (date_time_to_format, date_format.format_string, date_string, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        osp$append_status_parameter (osc$status_parameter_delimiter, date_string.value (1, date_string.size),
              message_status);
        clp$convert_date_time_to_string (date_time_to_format, time_format.format_string, time_string, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        osp$append_status_parameter (osc$status_parameter_delimiter, time_string.value (1, time_string.size),
              message_status);
        osp$generate_log_message ($pmt$ascii_logset[pmc$job_log], message_status, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        pmp$get_job_mode (job_mode, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        IF job_mode = jmc$interactive_connected THEN
          osp$generate_output_message (message_status, status);
        IFEND;
      IFEND;
    IFEND;

  PROCEND avp$display_pw_exp_warning;
?? TITLE := '    avp$end_subutility_session', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to end an ADMINISTER_VALIDATIONS subutility session.

  PROCEDURE [XDCL, #GATE] avp$end_subutility_session
    (    record_id: ost$name;
         rewrite_record: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      data_record: ^avt$template_file_record,
      data_record_size: 0 .. avc$max_template_record_size,
      description_record: ^avt$template_file_record,
      description_record_size: 0 .. avc$max_template_record_size,
      description_record_name: ost$name,
      field_count: avt$field_count,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;

{ Find the information for this subutility session within the validation record information chain.

    find_validation_record_info (record_id, validation_record_info, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Update the validation file if specified.

    IF rewrite_record THEN
      PUSH data_record: [[REP avc$max_template_record_size OF cell]];
      RESET data_record;
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      avp$read_data_record (validation_record_info^.key.value, avc$update_access, FALSE, data_record,
            data_record_size, description_record, description_record_size, description_record_name,
            field_count, file_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      avp$rewrite_data_record (validation_record_info^.key.value, TRUE, data_record, description_record,
            validation_record_info^.field_value_list, file_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

{ Emit audit statistics for changed fields.

      IF avp$security_option_active (avc$vso_security_audit) THEN
        field_value_list_entry := validation_record_info^.field_value_list;
        WHILE field_value_list_entry <> NIL DO
          emit_chg_value_audit_statistic (description_record_name, file_information.file_name,
                validation_record_info^.key, field_value_list_entry^.field_name, status);
          field_value_list_entry := field_value_list_entry^.forward;
        WHILEND
      IFEND;
    IFEND;

{ Release the validation record information from the subuility information chain.

    avp$release_record_id (record_id, status);

  PROCEND avp$end_subutility_session;
?? TITLE := '    PMP$GET_ACCOUNT_PROJECT', EJECT ??

  PROCEDURE [XDCL, #GATE] pmp$get_account_project (VAR account: avt$account_name;
    VAR project: avt$project_name;
    VAR status: ost$status);

    status.normal := TRUE;

    account := avv$account_name;
    project := avv$project_name;

  PROCEND pmp$get_account_project;

?? TITLE := '    avp$get_command_table', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used by ADMINISTER_VALIDATIONS to get the command table information stored in the record
{   utility information of the validation file.

  PROCEDURE [XDCL, #GATE] avp$get_command_table
    (    record_id: ost$name;
     VAR command_table_work_area: ^SEQ ( * );
     VAR command_table: ^clt$command_table;
     VAR status: ost$status);

    VAR
      command_table_entry: ^clt$command_table_entry,
      deleted_field_count: avt$field_count,
      deleted_field_names: ^array [1 .. * ] of ost$name,
      index: integer,
      number_of_entries: integer,
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      validation_record_info: ^avt$validation_record_info,
      record_utility_info_header: ^avt$record_utility_info_header;

?? NEWTITLE := 'deleted_field', EJECT ??
{ PURPOSE
{   This function is used to determine if a field is a deleted field.

    FUNCTION deleted_field
      (    field_name: ost$name;
           deleted_field_names: ^array [1 .. * ] of ost$name;
           deleted_field_count: avt$field_count): boolean;

      VAR
        deleted_field_index: integer;

      deleted_field := FALSE;

    /find_deleted_field/
      FOR deleted_field_index := 1 TO deleted_field_count DO
        IF field_name < deleted_field_names^ [deleted_field_index] THEN
          EXIT /find_deleted_field/;
        ELSEIF field_name = deleted_field_names^ [deleted_field_index] THEN
          deleted_field := TRUE;
          EXIT /find_deleted_field/;
        IFEND;
      FOREND /find_deleted_field/;

    FUNCEND deleted_field;
?? OLDTITLE ??
?? NEWTITLE := 'hide_unnecessary_commands', EJECT ??
{ PURPOSE
{   This procedure is used to change the availability of a subcommand based on the executing user's authority
{   relative to the authority values of the validation field.

    PROCEDURE hide_unnecessary_commands
      (    field_name: ost$name;
           caller_authority: avt$validation_authority;
           description_record: ^avt$template_file_record;
       VAR command_table_entry: clt$command_table_entry);

      VAR
        default_value: avt$field_value,
        descriptive_text: ^avt$descriptive_text,
        field_utility_information: ^avt$field_utility_information,
        field_work_area: ^seq (*),
        local_status: ost$status,
        type_specification: avt$type_specification,
        utility_information: ^avt$utility_information;

      IF field_name <> osc$null_name THEN
        local_status.normal := TRUE;

{ Get the field description from the description record.

        PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
        RESET field_work_area;
        avp$get_field_description (field_name, description_record, field_work_area, type_specification,
              default_value, descriptive_text, utility_information, local_status);
        IF NOT local_status.normal THEN
          RETURN;
        IFEND;

{ Access the field utility information.

        RESET utility_information;
        NEXT field_utility_information IN utility_information;
        IF field_utility_information = NIL THEN
          RETURN;
        IFEND;

        IF command_table_entry.procedure_name = avc$display_field_value THEN
          IF field_utility_information^.display_authority > caller_authority THEN
            command_table_entry.availability := clc$advanced_usage_entry;
          IFEND;
        ELSE
          IF field_utility_information^.change_authority > caller_authority THEN
            command_table_entry.availability := clc$advanced_usage_entry;
          IFEND;
        IFEND;
      IFEND;

    PROCEND hide_unnecessary_commands;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

{ Find the information for this subutility session within the validation record information chain.

    find_validation_record_info (record_id, validation_record_info, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Access the command table information within the record utility information.

    RESET validation_record_info^.record_utility_information;
    NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('AVP$GET_COMMAND_TABLE', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    NEXT record_utility_info_array: [1 .. record_utility_info_header^.number_of_entries] IN
          validation_record_info^.record_utility_information;
    IF record_utility_info_array = NIL THEN
      corrupted_sequence ('AVP$GET_COMMAND_TABLE', 'COMMAND_TABLE', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;

{ Retrieve a list of all deleted fields if there are any.

    PUSH deleted_field_names: [1 .. avc$maximum_field_count];
    avp$get_field_names (-$avt$field_kind_set [], TRUE, validation_record_info^.description_record,
          deleted_field_names^, deleted_field_count, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Build the command table to pass back to the caller

    RESET command_table_work_area;
    number_of_entries := 0;
    FOR index := 1 TO record_utility_info_header^.number_of_entries DO

{ Skip any deleted fields.

      IF NOT deleted_field (record_utility_info_array^ [index].field_name, deleted_field_names,
            deleted_field_count) THEN
        NEXT command_table_entry IN command_table_work_area;
        IF command_table_entry = NIL THEN
          corrupted_sequence ('AVP$GET_COMMAND_TABLE', 'COMMAND_TABLE', 'RECORD_UTILITY_INFORMATION', status);
          osp$set_status_abnormal ('AV', ave$corrupted_sequence, '', status);
          RETURN;
        IFEND;
        command_table_entry^ := record_utility_info_array^ [index].command_table_entry;
        hide_unnecessary_commands (record_utility_info_array^ [index].field_name,
              validation_record_info^.caller_authority, validation_record_info^.description_record,
              command_table_entry^);
        number_of_entries := number_of_entries + 1;
      IFEND;
    FOREND;

{ Allocate the correct size sequence in the command table work area.

    RESET command_table_work_area;
    NEXT command_table: [1 .. number_of_entries] IN command_table_work_area;
    IF command_table = NIL THEN
      corrupted_sequence ('AVP$GET_COMMAND_TABLE', 'COMMAND_TABLE', 'RECORD_UTILITY_INFORMATION', status);
      osp$set_status_abnormal ('AV', ave$corrupted_sequence, '', status);
      RETURN;
    IFEND;

  PROCEND avp$get_command_table;
?? TITLE := '    avp$get_field_name', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used by ADMINISTER_VALIDATIONS for the purpose of determining the field name that is
{   associated with the subcommand that the user has entered.

  PROCEDURE [XDCL, #GATE] avp$get_field_name
    (    record_id: ost$name;
     VAR field_name: ost$name;
     VAR command_name: ost$name;
     VAR status: ost$status);

    VAR
      block: ^clt$block,
      index: integer,
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      validation_record_info: ^avt$validation_record_info,
      record_utility_info_header: ^avt$record_utility_info_header;

    status.normal := TRUE;

{ Find the information for this subutility session within the validation record information chain.

    find_validation_record_info (record_id, validation_record_info, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Access the command table information within the record utility information.

    RESET validation_record_info^.record_utility_information;
    NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('AVP$GET_FIELD_NAME', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      osp$set_status_abnormal ('AV', ave$corrupted_sequence, '', status);
      RETURN;
    IFEND;
    NEXT record_utility_info_array: [1 .. record_utility_info_header^.number_of_entries] IN
          validation_record_info^.record_utility_information;
    IF record_utility_info_array = NIL THEN
      corrupted_sequence ('AVP$GET_COMMAND_TABLE', 'COMMAND_TABLE', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;

{ Retrieve the last command entered by the user.

    clp$find_current_block (block);

    command_name := block^.label;
    field_name := osc$null_name;

{ Find the field name associated with this command.

  /find_field_name/
    FOR index := 1 TO record_utility_info_header^.number_of_entries DO
      IF command_name = record_utility_info_array^ [index].command_table_entry.name THEN
        field_name := record_utility_info_array^ [index].field_name;
        EXIT /find_field_name/;
      IFEND;
    FOREND /find_field_name/;

    IF field_name = osc$null_name THEN
      osp$set_status_abnormal ('AV', ave$unable_to_find_field_name, command_name, status);
      RETURN;
    IFEND;

  PROCEND avp$get_field_name;
?? TITLE := '    avp$get_validation_field_kind', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to return the field kind of a specified validation field name.

  PROCEDURE [XDCL, #GATE] avp$get_validation_field_kind
    (    field_name: ost$name;
         validation_record_name: ost$name;
     VAR field_kind: avt$field_kind;
     VAR validation_file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      descriptive_text: ^avt$descriptive_text,
      field_work_area: ^seq (*),
      type_specification: avt$type_specification,
      utility_information: ^avt$utility_information;

    status.normal := TRUE;

{ Push a work area to hold the description record.

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;

{ Retrieve the description record.

    avp$get_description_record (validation_record_name, description_record, validation_file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Retrieve the field description for the specified field from the description record.

    PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
    RESET field_work_area;
    avp$get_field_description (field_name, description_record, field_work_area, type_specification,
          default_value, descriptive_text, utility_information, status);
    IF status.normal OR (status.condition = ave$field_was_deleted) THEN
      field_kind := type_specification.kind;
    IFEND;

  PROCEND avp$get_validation_field_kind;
?? TITLE := '    avp$get_validation_field_names', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to retrieve a list of active fields within a validation record, or a list of
{   inactive fields within a validation record.

  PROCEDURE [XDCL, #GATE] avp$get_validation_field_names
    (    validation_record_name: ost$name;
         desired_field_kinds: avt$field_kind_set;
         return_deleted_fields: boolean;
     VAR field_names: avt$name_list;
     VAR field_count: avt$field_count;
     VAR validation_file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      description_record: ^avt$template_file_record;

    status.normal := TRUE;

{ Push a work area to hold the description record.

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;

{ Retrieve the description record.

    avp$get_description_record (validation_record_name, description_record, validation_file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Extract the desired field names from the validation record.

    avp$get_field_names (desired_field_kinds, return_deleted_fields, description_record, field_names,
          field_count, status);

  PROCEND avp$get_validation_field_names;
?? TITLE := '    avp$open_validation_file', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to open a validation file.  If the validation file does not previously exist an
{   empty one will be created.  If the validation file exists and has a password then the password is
{   verified.  If a new password is specified the new password is updated.  (if the caller has the required
{   authority)

  PROCEDURE [XDCL, #GATE] avp$open_validation_file
    (    file_reference: fst$file_reference;
         old_password: ^ost$name;
         new_password: ^ost$name;
         create_file: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      validation_file_type: avt$validation_file_type,
      caller_id: ost$caller_identifier,
      family_from_path: ost$family_name,
      file_path: fst$path,
      file_path_size: fst$path_size,
      ignore_status: ost$status;

?? NEWTITLE := 'get_val_file_path_info', EJECT ??

{ PURPOSE:
{   This procedure creates a new validation file.

    PROCEDURE get_val_file_path_info
      (    file_reference: fst$file_reference;
       VAR family_from_path: ost$family_name;
       VAR validation_file_type: avt$validation_file_type;
       VAR file_path: fst$path;
       VAR file_path_size: fst$path_size;
       VAR status: ost$status);

      VAR
        evaluated_file_reference: fst$evaluated_file_reference,
        executing_id: ost$user_identification;

      status.normal := TRUE;

      validation_file_type := avc$vft_other;

{ Determine the family name and user name from the specified path.

      clp$evaluate_file_reference (file_reference, $clt$file_ref_parsing_options[], TRUE,
            evaluated_file_reference, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$convert_file_ref_to_string (evaluated_file_reference, FALSE, file_path, file_path_size, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF evaluated_file_reference.number_of_path_elements >= 3 THEN
        family_from_path := fsp$path_element (^evaluated_file_reference, 1)^;
      ELSE
        family_from_path := osc$null_name;
      IFEND;

      IF (evaluated_file_reference.number_of_path_elements = 3) AND
            (fsp$path_element (^evaluated_file_reference, 2)^ = jmc$system_user) AND
            (fsp$path_element (^evaluated_file_reference, 3)^ = avc$validation_file_name) THEN
        pmp$get_user_identification (executing_id, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        IF executing_id.family = family_from_path THEN
          validation_file_type := avc$vft_active_system;
        ELSE
          validation_file_type := avc$vft_system;
        IFEND;
      IFEND;

      PROCEND get_val_file_path_info;
?? OLDTITLE ??
?? NEWTITLE := 'create_validation_file', EJECT ??

{ PURPOSE:
{   This procedure creates a new validation file.

    PROCEDURE create_validation_file
      (    file_reference: fst$file_reference;
           new_password: ^ost$name;
           family_from_path: ost$family_name;
           validation_file_type: avt$validation_file_type;
       VAR file_information: avt$template_file_information;
       VAR status: ost$status);

      VAR
        audit_information: sft$audit_information,
        evaluated_file_reference: fst$evaluated_file_reference,
        file_utility_information: ^avt$file_utility_information,
        group: pft$group,
        ignore_status: ost$status,
        new_validation_file_password: avt$password,
        path: ^pft$path;

        status.normal := TRUE;

{ Create the validation file.

        avp$open_template_file (file_reference, TRUE, file_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

      /new_file_open/
        BEGIN

{ If it is a system validation file put a permit on it.

          IF validation_file_type >= avc$vft_system THEN
            PUSH path: [1 .. 3];
            path^ [1] := family_from_path;
            path^ [2] := jmc$system_user;
            path^ [3] := avc$validation_file_name;
            group.group_type := pfc$public;
            pfp$permit (path^, group, $pft$permit_selections [pfc$read, pfc$shorten, pfc$append, pfc$modify],
                  $pft$share_selections [pfc$read, pfc$shorten, pfc$append, pfc$modify], osc$null_name,
                  status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;

{ Initialize the file utility information.

          PUSH file_utility_information;
          file_utility_information^.new_file := TRUE;
          IF (new_password = NIL) OR (new_password^ = osc$null_name) THEN
            file_utility_information^.password := osc$null_name;
          ELSE
            avp$encrypt_password (osc$null_name, new_password^, new_validation_file_password, status);
            IF NOT status.normal THEN
              EXIT /new_file_open/;
            IFEND;
            file_utility_information^.password := new_validation_file_password;
          IFEND;
          file_utility_information^.version := avc$validation_file_version;
          avp$change_file_utility_info (#SEQ (file_utility_information^), file_information, status);
          IF NOT status.normal THEN
            EXIT /new_file_open/;
          IFEND;

{ Initialize the system defined validation records.

          initialize_validation_records (file_information, status);
          IF NOT status.normal THEN
            EXIT /new_file_open/;
          IFEND;

{ Initialize the system defined validation fields.

          initialize_validation_fields (family_from_path, file_information, status);
          IF NOT status.normal THEN
            EXIT /new_file_open/;
          IFEND;
        END /new_file_open/;

{ Emit an audit statistic if a security password was assigned to the new validation file.

        IF (avp$security_option_active (avc$vso_security_audit)) AND
              (file_utility_information^.password <> osc$null_name) THEN
          audit_information.audited_operation := sfc$ao_val_change_security_pw;
          audit_information.change_security_password.validation_file_p := ^file_information.file_name;
          sfp$emit_audit_statistic (audit_information, status);
        IFEND;

        IF NOT status.normal THEN
          avp$close_template_file (file_information, ignore_status);
          RETURN;
        IFEND;
      PROCEND create_validation_file;
?? OLDTITLE ??
?? NEWTITLE := 'verify_security_password', EJECT ??

{ PURPOSE:
{   This procedure verifies and updates the password on a validation file.

      PROCEDURE verify_security_password
        (    old_password: ^ost$name;
             new_password: ^ost$name;
         VAR file_information: avt$template_file_information;
         VAR status: ost$status);

      VAR
        audit_information: sft$audit_information,
        file_utility_information: ^avt$file_utility_information,
        new_validation_file_password: avt$password,
        old_validation_file_password: avt$password,
        temp_validation_file_password: avt$password,
        utility_information: ^avt$utility_information;

        status.normal := TRUE;

{ Retrieve the current password from the file utility information.

        PUSH utility_information: [[REP 1 OF avt$file_utility_information]];
        RESET utility_information;
        avp$get_file_utility_info (utility_information, file_information, status);
        RESET utility_information;
        NEXT file_utility_information IN utility_information;
        IF file_utility_information = NIL THEN
          corrupted_sequence ('AVP$OPEN_VALIDATION_FILE', 'PASSWORD', 'FILE_UTILITY_INFORMATION', status);
          RETURN;
        IFEND;

{ If a password exists for the file verify the caller has specified the correct password.

      /verify_password/
        BEGIN
          IF file_utility_information^.password <> osc$null_name THEN
            IF old_password <> NIL THEN
              avp$encrypt_password (osc$null_name, old_password^, old_validation_file_password, status);
              IF NOT status.normal THEN
                EXIT /verify_password/;
              IFEND;
              IF old_validation_file_password <> file_utility_information^.password THEN
                temp_validation_file_password := old_validation_file_password;
                avp$old_encrypt_password (osc$null_name, old_password^, old_validation_file_password, status);
                IF NOT status.normal THEN
                  EXIT /verify_password/;
                IFEND;
                IF old_validation_file_password <> file_utility_information^.password THEN
                  osp$set_status_abnormal ('AV', ave$old_password_not_valid, 'validation file', status);
                  EXIT /verify_password/;
                IFEND;

{ If the current password was not encrypted with the current algorithm and a new password was not
{ specified, then encrypt the current password with the current algorithm.

                IF new_password = NIL THEN
                  file_utility_information^.password := temp_validation_file_password;
                  avp$change_file_utility_info (#SEQ(file_utility_information^), file_information, status);
                  IF NOT status.normal THEN
                    EXIT /verify_password/;
                  IFEND;
                IFEND;
              IFEND;
            ELSEIF new_password = NIL THEN
              osp$set_status_abnormal ('AV', ave$must_specify_password, '', status);
              EXIT /verify_password/;
            ELSEIF NOT avp$system_administrator () THEN
              osp$set_status_abnormal ('AV', ave$can_not_set_new_without_old, '', status);
              EXIT /verify_password/;
            IFEND;
          ELSE
            IF old_password <> NIL THEN
              osp$set_status_abnormal ('AV', ave$no_password_on_file, '', status);
              EXIT /verify_password/;
            IFEND;
          IFEND;

{ If a new password was specified update it.

          IF new_password <> NIL THEN
            IF new_password^ = osc$null_name THEN
              file_utility_information^.password := osc$null_name;
            ELSE
              avp$encrypt_password (osc$null_name, new_password^, new_validation_file_password, status);
              IF NOT status.normal THEN
                EXIT /verify_password/;
              IFEND;
              file_utility_information^.password := new_validation_file_password;
            IFEND;
            avp$change_file_utility_info (#SEQ (file_utility_information^), file_information, status);
          IFEND;
         END /verify_password/;

{ Emit audit statistic if the security password was changed.

         IF (avp$security_option_active (avc$vso_security_audit)) AND (new_password <> NIL) THEN
           IF old_password = NIL THEN
             audit_information.audited_operation := sfc$ao_val_force_security_pw;
             audit_information.force_security_password.validation_file_p := ^file_information.file_name;
           ELSE
             audit_information.audited_operation := sfc$ao_val_change_security_pw;
             audit_information.change_security_password.validation_file_p := ^file_information.file_name;
           IFEND;
           sfp$emit_audit_statistic (audit_information, status);
         IFEND;

      PROCEND verify_security_password;
?? OLDTITLE, EJECT ??
    #CALLER_ID (caller_id);

    status.normal := TRUE;

    get_val_file_path_info (file_reference, family_from_path, validation_file_type, file_path, file_path_size,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify ability to access an alternate family's validation file.

    ?IF NOT avc$compile_test_code THEN
    IF (caller_id.ring > osc$tsrv_ring) AND (NOT avp$system_administrator ()) AND
          (validation_file_type <> avc$vft_active_system) THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;
    ?IFEND

    avp$open_template_file (file_path (1, file_path_size), FALSE, file_information, status);
    IF (NOT status.normal) THEN
      IF ((status.condition = ame$file_not_known) OR (status.condition = pfe$unknown_permanent_file) OR
            (status.condition = pfe$unknown_cycle)) AND (create_file) THEN
        status.normal := TRUE;
      ELSE
        RETURN;
      IFEND;

      ?IF NOT avc$compile_test_code THEN
      IF (caller_id.ring > osc$tsrv_ring) AND (NOT avp$system_administrator ()) THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        RETURN;
      IFEND;
      ?IFEND

      create_validation_file (file_path (1, file_path_size), new_password, family_from_path,
            validation_file_type, file_information, status);
    ELSE

{ If the call was made by a system or family administrator, from above ring 3, check the security password.

      IF (caller_id.ring > osc$tsrv_ring) AND
            (avp$system_administrator () OR avp$family_administrator ()) THEN
        verify_security_password (old_password, new_password, file_information, status);
        IF NOT status.normal THEN
          avp$close_template_file (file_information, ignore_status);
        IFEND;
      IFEND;
    IFEND;

  PROCEND avp$open_validation_file;
?? TITLE := '    avp$open_system_validation_file', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to open a validation file.  This interface may only be used to open an existing
{   validation file.

  PROCEDURE [XDCL] avp$open_system_validation_file
    (    family: ost$family_name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      family_name_size: 0 .. osc$max_name_size,
      file_path: fst$path;

    status.normal := TRUE;

    family_name_size := clp$trimmed_string_size (family);
    file_path := ':';
    file_path (2, *) := family;
    ?IF NOT avc$compile_test_code THEN
      file_path (family_name_size + 2, *) := '.$SYSTEM.$VALIDATIONS';
    ?ELSE
      file_path := '$USER.$VALIDATIONS';
    ?IFEND
    avp$open_template_file (file_path (1, family_name_size + 23), FALSE, file_information, status);

  PROCEND avp$open_system_validation_file;
?? TITLE := '    avp$prevalidate_job', EJECT ??
*copyc avh$prevalidate_job
{ NOTES:
{
{   The following items are always validated:
{     The user is validated for access to the family.
{     The user's password is checked for expiration.
{
{   The following items are optional validations:
{     Password. (In it's unecrypted form)
{     Account membership if running at account level.
{     Account or Project membership if running at project level.
{     Job Class.
{     Job execution ring.
{     Job limits.
{     Required capabilites.
{
{   The following items may be returned:
{     Job class batch and interactive defaults.
{     The list of valid job classes.
{     Job limit values.
{     Capabilities.
{     Encrypted Password.
{
{   This interface must never be GATED above ring 3 because of the security problem that would
{   result from the feature of returning the encrypted password.

  PROCEDURE [XDCL] avp$prevalidate_job
    (    user_name: ost$user_name;
         family_name: ost$family_name;
         validation_attributes: ^avt$validation_items;
         default_attributes: ^avt$validation_items;
     VAR status: ost$status);

    VAR
      data_size_to_send_to_server: dft$send_data_size,
      p_data_received_from_server: dft$p_receive_data,
      p_data_to_send_to_server: dft$p_send_data,
      p_params_received_from_server: dft$p_receive_parameters,
      p_params_to_send_to_server: dft$p_send_parameters,
      params_size_to_send_to_server: dft$send_parameter_size,
      queue_entry_location: dft$rpc_queue_entry_location,
      server_locator: dft$server_location,
      ignore_status: ost$status,
      validation_level: avt$validation_level;

?? TITLE := '      client_prevalidate_job', EJECT ??
    PROCEDURE client_prevalidate_job
      (    validation_level: avt$validation_level;
           user_name: ost$user_name;
           family_name: ost$family_name;
           validation_attributes: ^avt$validation_items;
           default_attributes: ^avt$validation_items;
       VAR p_params_to_send_to_server: dft$p_send_parameters;
       VAR p_data_to_send_to_server: dft$p_send_data;
       VAR params_size_to_send_to_server: dft$send_parameter_size;
       VAR data_size_to_send_to_server: dft$send_data_size;
       VAR p_params_received_from_server: dft$p_receive_parameters;
       VAR p_data_received_from_server: dft$p_receive_data;
       VAR status: ost$status);

       VAR
           ignore_recovery_occured: boolean;

?? TITLE := '        build_info_to_send_to_server', EJECT ??
      PROCEDURE build_info_to_send_to_server
        (    validation_level: avt$validation_level;
             user_name: ost$user_name;
             family_name: ost$family_name;
             validation_attributes: ^avt$validation_items;
             default_attributes: ^avt$validation_items;
         VAR p_params_to_send_to_server: dft$p_send_parameters;
         VAR p_data_to_send_to_server: dft$p_send_data;
         VAR params_size_to_send_to_server: dft$send_parameter_size;
         VAR data_size_to_send_to_server: dft$send_data_size);

        VAR
          send_default_attributes: ^avt$validation_items,
          send_validation_attributes: ^avt$validation_items,
          server_prevalidate_job_input: ^avt$server_prevalidate_job_in;

        params_size_to_send_to_server := 0;
        data_size_to_send_to_server := 0;

  { Copy the parameters to be used.

        NEXT server_prevalidate_job_input IN p_params_to_send_to_server;
        server_prevalidate_job_input^.validation_level := validation_level;
        server_prevalidate_job_input^.user_name := user_name;
        server_prevalidate_job_input^.family_name := family_name;

  { Copy the validation attributes to be used.

        IF validation_attributes = NIL THEN
          server_prevalidate_job_input^.number_of_val_attributes := 0;
        ELSE
          server_prevalidate_job_input^.number_of_val_attributes := UPPERBOUND (validation_attributes^);
          NEXT send_validation_attributes: [1 .. UPPERBOUND (validation_attributes^)] IN
                p_params_to_send_to_server;
          send_validation_attributes^ := validation_attributes^;
        IFEND;

  { Copy the default attributes requested.

        IF default_attributes = NIL THEN
          server_prevalidate_job_input^.number_of_def_attributes := 0;
        ELSE
          server_prevalidate_job_input^.number_of_def_attributes := UPPERBOUND (default_attributes^);
          NEXT send_default_attributes: [1 .. UPPERBOUND (default_attributes^)] IN
                p_params_to_send_to_server;
          send_default_attributes^ := default_attributes^;
        IFEND;

        params_size_to_send_to_server := i#current_sequence_position (p_params_to_send_to_server);

      PROCEND build_info_to_send_to_server;
  ?? TITLE := '        extract_info_sent_from_server', EJECT ??
      PROCEDURE extract_info_sent_from_server
        (    default_attributes: ^avt$validation_items;
         VAR p_params_received_from_server: dft$p_receive_parameters;
         VAR p_data_received_from_server: dft$p_receive_data);

        VAR
          get_default_attributes: ^avt$validation_items,
          get_valid_job_classes: ^array [1 .. * ] of ost$name,
          index: integer,
          index2: integer,
          item_index: integer,
          label: ^ost$name,
          name: ^ost$name,
          number_of_labeled_names: ^integer,
          number_of_names: ^integer;

        IF default_attributes <> NIL THEN
          NEXT get_default_attributes: [1 .. UPPERBOUND (default_attributes^)]
                IN p_params_received_from_server;
          FOR item_index := 1 TO UPPERBOUND (get_default_attributes^) DO
            IF get_default_attributes^ [item_index].key = avc$valid_job_classes_key THEN
              get_default_attributes^ [item_index].job_classes :=
                    default_attributes^ [item_index].job_classes;
              NEXT get_valid_job_classes: [1 .. UPPERBOUND (default_attributes^ [item_index].
                    job_classes^)] IN p_data_received_from_server;
              FOR index := 1 TO  UPPERBOUND (default_attributes^ [item_index].job_classes^) DO
                default_attributes^ [item_index].job_classes^ [index] := get_valid_job_classes^ [index];
              FOREND;
            ELSEIF get_default_attributes^ [item_index].key = avc$labeled_names_key THEN
              get_default_attributes^ [item_index].work_area:=
                    default_attributes^ [item_index].work_area;

              NEXT number_of_labeled_names IN p_data_received_from_server;
              NEXT get_default_attributes^ [item_index].labeled_names: [1 .. number_of_labeled_names^] IN
                    get_default_attributes^ [item_index].work_area;
              FOR index := 1 TO number_of_labeled_names^ DO
                NEXT label IN p_data_received_from_server;
                NEXT get_default_attributes^ [item_index].labeled_names^ [index].label IN
                    get_default_attributes^ [item_index].work_area;
                get_default_attributes^ [item_index].labeled_names^ [index].label^ := label^;
                NEXT number_of_names IN p_data_received_from_server;
                NEXT get_default_attributes^ [item_index].labeled_names^ [index].names:
                      [1 .. number_of_names^] IN get_default_attributes^ [item_index].work_area;
                FOR index2 := 1 TO number_of_names^ DO
                  NEXT name IN p_data_received_from_server;
                  get_default_attributes^ [item_index].labeled_names^ [index].names^ [index2] := name^;
                FOREND;
              FOREND;
            IFEND;
            default_attributes^ [item_index] := get_default_attributes^ [item_index];
          FOREND;
        IFEND;

      PROCEND extract_info_sent_from_server;
  ?? OLDTITLE, EJECT ??

{ Build the parameters to send to the server.
{ This repeat loop will execute at most twice.

    REPEAT
      build_info_to_send_to_server (validation_level, user_name, family_name, validation_attributes,
            default_attributes, p_params_to_send_to_server, p_data_to_send_to_server,
            params_size_to_send_to_server, data_size_to_send_to_server);

{ Make the remote procedure call.

      dfp$send_remote_procedure_call (queue_entry_location, dfc$prevalidate_job,
            params_size_to_send_to_server, data_size_to_send_to_server, p_params_received_from_server,
            p_data_received_from_server, status);
      IF NOT status.normal AND (status.condition = dfe$job_needs_recovery) THEN
        dfp$end_ch_remote_proc_call (queue_entry_location, ignore_status);
        dfp$check_job_recovery (ignore_recovery_occured);
        dfp$begin_ch_remote_proc_call (server_locator, FALSE, queue_entry_location,
            p_params_to_send_to_server, p_data_to_send_to_server, ignore_status);
        IF NOT ignore_status.normal THEN
          status := ignore_status;
        IFEND;
      IFEND;

{ Extract the information sent by the server.

     IF status.normal THEN
        extract_info_sent_from_server (default_attributes, p_params_received_from_server,
              p_data_received_from_server);
     IFEND;
    UNTIL status.normal OR (status.condition <> dfe$job_needs_recovery);

    PROCEND client_prevalidate_job;
?? OLDTITLE ??
?? NEWTITLE := 'dfp$remote_procedure_call_ch', EJECT ??

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

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

      dfp$ch_cleanup;
      osp$set_status_from_condition (dfc$file_server_id, condition, save, status, handler_status);
      EXIT avp$prevalidate_job;

    PROCEND dfp$remote_procedure_call_ch;
*block
*copyc dfp$begin_ch_remote_proc_call
*copyc dfp$end_ch_remote_proc_call
*blockend
?? OLDTITLE, EJECT ??
    status.normal := TRUE;
    validation_level := avp$validation_level ();

    server_locator.server_location_selector := dfc$family_name;
    server_locator.family_name := family_name;
    ?IF avc$compile_test_code THEN
      status.normal := FALSE;
      status.condition := dfe$family_not_served;
    ?ELSE
    dfp$begin_ch_remote_proc_call (server_locator, FALSE, queue_entry_location, p_params_to_send_to_server,
          p_data_to_send_to_server, status);
    ?IFEND
    IF status.normal THEN

      client_prevalidate_job (validation_level, user_name, family_name, validation_attributes,
            default_attributes, p_params_to_send_to_server, p_data_to_send_to_server,
            params_size_to_send_to_server, data_size_to_send_to_server, p_params_received_from_server,
            p_data_received_from_server, status);

      IF status.normal THEN
        dfp$end_ch_remote_proc_call (queue_entry_location, status);
      ELSE
        dfp$end_ch_remote_proc_call (queue_entry_location, ignore_status);
      IFEND;

{ Prevalidate was done on the server so return.

      RETURN;
    ELSEIF status.condition = dfe$family_not_served THEN
      status.normal := TRUE;
      prevalidate_job (validation_level, user_name, family_name, validation_attributes,
            default_attributes, status);
    IFEND;

  PROCEND avp$prevalidate_job;
?? TITLE := '    avp$release_record_id', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to clear a validation record information entry
{ from the chain.
{
{ DESIGN:
{
{   The RECORD_ID is used to search the chain and when a match is found the
{ task private data is FREEed and the associated temporary scratch segment is
{ released.
{

  PROCEDURE [XDCL, #GATE] avp$release_record_id
    (    record_id: ost$name;
     VAR status: ost$status);

    VAR
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;

{ Find the information within the validation record information chain.

    find_validation_record_info (record_id, validation_record_info, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Remove the entry from the validation record information chain.

    IF validation_record_info^.backward <> NIL THEN
      validation_record_info^.backward^.forward := validation_record_info^.forward;
    ELSE
      avv$validation_record_info := validation_record_info^.forward;
    IFEND;
    IF validation_record_info^.forward <> NIL THEN
      validation_record_info^.forward^.backward := validation_record_info^.backward;
    IFEND;

{ If a scratch segment was created then delete it.

    IF validation_record_info^.work_area.sequence_pointer <> NIL THEN
      mmp$delete_scratch_segment (validation_record_info^.work_area, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Free the data record work area in task private.

    IF validation_record_info^.data_record <> NIL THEN
      FREE validation_record_info^.data_record IN osv$task_private_heap^;
    IFEND;

{ Free the description record work area in task private.

    IF validation_record_info^.description_record <> NIL THEN
      FREE validation_record_info^.description_record IN osv$task_private_heap^;
    IFEND;

{ Free the validation record info work area in task private.

    FREE validation_record_info IN osv$task_private_heap^;

  PROCEND avp$release_record_id;
?? TITLE := '    avp$reorganize_validation_file', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to restructure the validation file.
{
*copyc avh$reorganize_validation_file
  PROCEDURE [XDCL, #GATE] avp$reorganize_validation_file
    (    old_file_name: fst$file_reference;
         new_file_name: fst$file_reference;
     VAR status: ost$status);

    status.normal := TRUE;
    osp$verify_system_privilege;
    avp$restructure_template_file (old_file_name, new_file_name, status);

  PROCEND avp$reorganize_validation_file;
?? TITLE := '    avp$ring_min', EJECT ??
*copyc avh$ring_min

  FUNCTION [XDCL, #GATE] avp$ring_min: ost$ring;

    IF (avp$system_administrator()) THEN
      avp$ring_min := osc$tsrv_ring;
    ELSE
      avp$ring_min := avv$minimum_ring;
    IFEND;

  FUNCEND avp$ring_min;
?? TITLE := '    avp$ring_nominal', EJECT ??
*copyc avh$ring_nominal

  FUNCTION [XDCL, #GATE] avp$ring_nominal: ost$ring;

    avp$ring_nominal := avv$nominal_ring;

  FUNCEND avp$ring_nominal;
?? TITLE := '    avp$set_validation_level', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to set the system wide validation level.
{
{ DESIGN:
{
{   This interface may only be called by a system administrator.
{
{   The validation level is stored in a system constant.
{

  PROCEDURE [XDCL, #GATE] avp$set_validation_level
    (    validation_level: avt$validation_level;
     VAR status: ost$status);

    status.normal := TRUE;

{ Verify system administration capability.

    IF NOT avp$system_administrator () THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Store the specified validation level in the system constant.

    ?IF avc$compile_test_code THEN
      avv$validation_level := $INTEGER (validation_level);
    ?ELSE
      syp$store_system_constant (avc$validation_level_const_name, $INTEGER (validation_level), status);
    ?IFEND

  PROCEND avp$set_validation_level;
?? TITLE := '    avp$capabilities_active_any', EJECT ??

  FUNCTION [XDCL, #GATE, UNSAFE] avp$capabilities_active_any
    (    capabilities: avt$conditional_capabilities) : boolean;

    VAR
      current_block: ^clt$block;

    ?IF avc$compile_test_code THEN
      avp$capabilities_active_any := capabilities * avv$active_sou_capabilities <>
            $avt$conditional_capabilities [];
    ?ELSE
      clp$find_current_block (current_block);
      avp$capabilities_active_any := capabilities * current_block^.active_capabilities <>
            $avt$conditional_capabilities [];
    ?IFEND

  FUNCEND avp$capabilities_active_any;
?? TITLE := '    avp$capability_active', EJECT ??
*copyc avh$capability_active

  FUNCTION [XDCL, #GATE, UNSAFE] avp$capability_active
    (    capability: avt$conditional_capability) : boolean;

    VAR
      current_block: ^clt$block;

    ?IF avc$compile_test_code THEN
      avp$capability_active := capability IN avv$active_sou_capabilities;
    ?ELSE
      clp$find_current_block (current_block);
      avp$capability_active := capability IN current_block^.active_capabilities;
    ?IFEND

  FUNCEND avp$capability_active;
?? TITLE := '    avp$replace_total_limits', EJECT ??
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to replace the values for total limit for a given
{ accumulating limit type field.
{
{ DESIGN:

  PROCEDURE [XDCL, #GATE] avp$replace_total_limits
    (    accum_limit_field_name: ost$name;
     VAR limit_update_info_array: ^array [1 .. * ] of avt$total_limit_update_record;
     VAR status: ost$status);

    VAR
      account_limit_applies: boolean,
      account_member_limit_applies: boolean,
      current_entry: integer,
      data_record: ^avt$template_file_record,
      default_value: avt$field_value,
      description: ost$string,
      description_record: ^avt$template_file_record,
      family_name: ost$family_name,
      field_utility_information: avt$field_utility_information,
      field_value_list: avt$field_value_list_entry,
      high_value_key: avt$validation_key,
      ignore_status: ost$status,
      limit_update_key: avt$validation_key,
      previous_family_name: ost$family_name,
      project_limit_applies: boolean,
      project_member_limit_applies: boolean,
      served_family: boolean,
      size: integer,
      type_specification: avt$type_specification,
      user_limit_applies: boolean,
      validation_file_information: avt$template_file_information,
      validation_file_key: avt$validation_key,
      validation_level: avt$validation_level;

?? NEWTITLE := 'sort_total_limit_update_info', EJECT ??

{ PURPOSE:
{   This procedure sorts the limit update records into the same order as the validation file.
{
{ DESIGN:
{   This sort is the "quick sort" algorithm described in:
{     The Art of Computer Programing, Volumne 3, by Knuth, published by Addison Wesley.

    PROCEDURE sort_total_limit_update_info
      (    total_limit_update_info_array: ^array [1 .. * ] of avt$total_limit_update_record;
       VAR status: ost$status);

      TYPE
        sort_stack_entry = record
          left_index: integer,
          right_index: integer,
          next_entry: ^sort_stack_entry,
        recend;

      VAR
        current_sort_stack_entry: ^sort_stack_entry,
        number_of_records: integer,
        right_index: integer,
        left_index: integer,
        forward_index: integer,
        record_to_insert: avt$total_limit_update_record;
?? EJECT ??

{ PURPOSE:
{   This procedure partitions the subfile being sorted into two subfiles. One which is all less than
{   a given entry in the file and one which is all greater than that entry.  These subfiles are
{   placed on the stack to be sorted later.

      PROCEDURE [INLINE] partition_into_subfiles
        (    left_index: integer;
             right_index: integer;
         VAR current_sort_stack_entry: ^sort_stack_entry);

        VAR
          current_left_index: integer,
          current_right_index: integer,
          subfile_partitioned: boolean;

        subfile_partitioned := FALSE;
        current_left_index := left_index;
        current_right_index := right_index;

{ An entry from within the subfile is picked, and its correct position is searched for within the file.
{ The midpoint entry within the subfile is picked to guard against the worst case condition of the file
{ already being in order.

        record_to_insert := total_limit_update_info_array^ [((right_index - left_index) DIV 2) + left_index];
        total_limit_update_info_array^ [((right_index - left_index) DIV 2) + left_index] :=
              total_limit_update_info_array^ [left_index];

        REPEAT
          WHILE (current_right_index >= 1) AND
                ((record_to_insert.family_name < total_limit_update_info_array^ [current_right_index].
                family_name) OR ((record_to_insert.family_name =
                total_limit_update_info_array^ [current_right_index].family_name) AND
                (record_to_insert.validation_key.value < total_limit_update_info_array^ [current_right_index].
                validation_key.value))) DO
            current_right_index := current_right_index - 1;
          WHILEND;
          IF current_right_index <= current_left_index THEN
            total_limit_update_info_array^ [current_left_index] := record_to_insert;
            put_on_stack (left_index, current_left_index, right_index, current_sort_stack_entry);
            subfile_partitioned := TRUE;
          ELSE
            total_limit_update_info_array^ [current_left_index] :=
                  total_limit_update_info_array^ [current_right_index];
            current_left_index := current_left_index + 1;
            WHILE (current_left_index <= number_of_records) AND
                  ((total_limit_update_info_array^ [current_left_index].family_name <
                  record_to_insert.family_name) OR ((total_limit_update_info_array^ [current_left_index].
                  family_name = record_to_insert.family_name) AND
                  (total_limit_update_info_array^ [current_left_index].validation_key.value <
                  record_to_insert.validation_key.value))) DO
              current_left_index := current_left_index + 1;
            WHILEND;
            IF current_right_index <= current_left_index THEN
              total_limit_update_info_array^ [current_right_index] := record_to_insert;
              put_on_stack (left_index, current_right_index, right_index, current_sort_stack_entry);
              subfile_partitioned := TRUE;
            ELSE
              total_limit_update_info_array^ [current_right_index] :=
                    total_limit_update_info_array^ [current_left_index];
              current_right_index := current_right_index - 1;
            IFEND;
          IFEND;
        UNTIL subfile_partitioned;

      PROCEND partition_into_subfiles;
?? EJECT ??

{ PURPOSE:
{   This procedure places an entry of left and right indices for a subfile on to a stack so that the
{   subfile can be sorted later.

      PROCEDURE [INLINE] put_on_stack
        (    left_index: integer;
             insert_index: integer;
             right_index: integer;
         VAR current_sort_stack_entry: ^sort_stack_entry);

        VAR
          new_sort_stack_entry: ^sort_stack_entry;

{ If the subfile is of less than 2 elements (1 or 0) then don't bother putting it on the stack.

        IF (right_index - insert_index) > 1 THEN
          PUSH new_sort_stack_entry;
          new_sort_stack_entry^.left_index := insert_index + 1;
          new_sort_stack_entry^.right_index := right_index;
          new_sort_stack_entry^.next_entry := current_sort_stack_entry;
          current_sort_stack_entry := new_sort_stack_entry;
        IFEND;

        IF (insert_index - left_index) > 1 THEN
          PUSH new_sort_stack_entry;
          new_sort_stack_entry^.left_index := left_index;
          new_sort_stack_entry^.right_index := insert_index - 1;
          new_sort_stack_entry^.next_entry := current_sort_stack_entry;
          current_sort_stack_entry := new_sort_stack_entry;
        IFEND;

      PROCEND put_on_stack;
?? EJECT ??

{ PURPOSE:
{   This procedure is used sort a subfile of M (9 for this implementation) or less records.  This is done
{   because straight insertion is faster than "quick sorting" for small subfiles.

      PROCEDURE insertion_sort_subfile
        (    left_index: integer;
             right_index: integer);

        FUNCTION insert_here: boolean;

          insert_here := (total_limit_update_info_array^ [backward_index].family_name <
                record_to_insert.family_name) OR ((total_limit_update_info_array^ [backward_index].
                family_name = record_to_insert.family_name) AND
                (total_limit_update_info_array^ [backward_index].validation_key.value <
                record_to_insert.validation_key.value));
        FUNCEND insert_here;

        VAR
          forward_index: integer,
          backward_index: integer,
          record_to_insert: avt$total_limit_update_record;

        FOR forward_index := (left_index + 1) TO right_index DO
          backward_index := forward_index - 1;
          record_to_insert := total_limit_update_info_array^ [forward_index];

        /find_insert_position/
          REPEAT
            IF insert_here () THEN
              EXIT /find_insert_position/;
            ELSE
              total_limit_update_info_array^ [backward_index + 1] :=
                    total_limit_update_info_array^ [backward_index];
              backward_index := backward_index - 1;
            IFEND;
          UNTIL backward_index = (left_index - 1);
          total_limit_update_info_array^ [backward_index + 1] := record_to_insert;

        FOREND;
      PROCEND insertion_sort_subfile;
?? EJECT ??
      status.normal := TRUE;

      number_of_records := UPPERBOUND (total_limit_update_info_array^);
      PUSH current_sort_stack_entry;
      current_sort_stack_entry^.left_index := 1;
      current_sort_stack_entry^.right_index := number_of_records;
      current_sort_stack_entry^.next_entry := NIL;

      WHILE current_sort_stack_entry <> NIL DO
        left_index := current_sort_stack_entry^.left_index;
        right_index := current_sort_stack_entry^.right_index;
        current_sort_stack_entry := current_sort_stack_entry^.next_entry;

        IF (right_index - left_index) < 9 THEN
          insertion_sort_subfile (left_index, right_index);
        ELSE
          partition_into_subfiles (left_index, right_index, current_sort_stack_entry);
        IFEND;
      WHILEND;

    PROCEND sort_total_limit_update_info;
?? OLDTITLE ??
?? NEWTITLE := '      get_next_update_entry', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to get a summarized record of all of the
{ update records starting at a given entry in the array whose keys
{ are the same.  The size that is returned is the total summed size from those
{ records.
{
{ DESIGN:
{
{   The current entry parameter returns the position of the last entry in the
{ array that has the returned key value.
{
{   If a family break occurs a high value key is returned to signify that an
{ "end of information" for that family has been found.  In which case the
{ current entry parameter is unchanged so that the next entry found will be the
{ first entry for the new family.
{
{   If the end of the array entries is found a null family name is returned
{ to signify that no more update information is available.
{

    PROCEDURE get_next_update_entry
      (    limit_update_info_array: ^array [1 .. * ] of avt$total_limit_update_record;
       VAR previous_family_name: ost$family_name;
       VAR family_name: ost$family_name;
       VAR key: avt$validation_key;
       VAR size: integer;
       VAR current_entry: integer);

      VAR
        next_entry: integer,
        type_specification: avt$type_specification;

      size := 0;

      IF (current_entry + 1) <= UPPERBOUND (limit_update_info_array^) THEN
        IF limit_update_info_array^ [current_entry + 1].family_name <> previous_family_name THEN

{ The end of the updates for the current family has been reached.

          key.value := high_value_key.value;

{ Reset the previous family flag for the next time through.

          previous_family_name := limit_update_info_array^ [current_entry + 1].family_name;
          RETURN;
        ELSE
          current_entry := current_entry + 1;
        IFEND;

{ Assign the values to return.

        family_name := limit_update_info_array^ [current_entry].family_name;
        key.value := limit_update_info_array^ [current_entry].validation_key.value;
        size := limit_update_info_array^ [current_entry].size;

{ Summarize the size for any records with like keys.

        next_entry := current_entry + 1;
        WHILE ((next_entry <= UPPERBOUND (limit_update_info_array^)) AND
              (limit_update_info_array^ [current_entry].family_name =
              limit_update_info_array^ [next_entry].family_name) AND
              (limit_update_info_array^ [current_entry].validation_key.value =
              limit_update_info_array^ [next_entry].validation_key.value)) DO
          size := size + limit_update_info_array^ [next_entry].size;
          current_entry := next_entry;
          next_entry := next_entry + 1;
        WHILEND;
      ELSE

{ The end of the update info array has been reached.

        family_name := osc$null_name;
        key.value := high_value_key.value;
      IFEND;

    PROCEND get_next_update_entry;
?? TITLE := '      get_next_validation_file_entry', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to get the next record from a validation file
{ that has a matching limit field and whose record type is within
{ the system validation level.
{
{   That is:  If the system is running at user level then the only user records
{                   are selected.
{             If the system is running at account level then the next account,
{                   account member, or user records are selected.
{             If the system is running at project level then any record may be
{                   selected.
{

    PROCEDURE get_next_validation_file_entry
      (    accum_limit_field_name: ost$name;
       VAR data_record: ^avt$template_file_record;
       VAR description_record: ^avt$template_file_record;
       VAR key: avt$validation_key;
       VAR field_value: avt$field_value;
       VAR file_information: avt$template_file_information;
       VAR status: ost$status);

      VAR
        default_value: avt$field_value,
        description_record_name: ost$name,
        descriptive_text: ^avt$descriptive_text,
        field_count: avt$field_count,
        record_to_update_found: boolean,
        type_specification: avt$type_specification,
        utility_information: ^avt$utility_information;

      status.normal := TRUE;

{ Read validation records until a record within the system validation level
{ is found.

      REPEAT
        RESET data_record;
        RESET description_record;

{ Get the next validation record.

        avp$read_next_data_record (avc$update_access, FALSE, key.value, data_record, description_record,
              description_record_name, field_count, file_information, status);
        IF NOT status.normal THEN
          IF status.condition = ave$end_of_template_file THEN
            key.value := high_value_key.value;
            status.normal := TRUE;
          IFEND;
          RETURN;
        IFEND;

{ Determine if the record read should be updated.

        record_to_update_found := FALSE;
        IF description_record_name = avc$user_record_name THEN
          IF user_limit_applies THEN
            record_to_update_found := TRUE;
          IFEND;
        ELSEIF description_record_name = avc$account_record_name THEN
          IF ((account_limit_applies) AND (validation_level > avc$user_level)) THEN
            record_to_update_found := TRUE;
          IFEND;
        ELSEIF description_record_name = avc$account_member_record_name THEN
          IF ((account_member_limit_applies) AND (validation_level > avc$user_level)) THEN
            record_to_update_found := TRUE;
          IFEND;
        ELSEIF description_record_name = avc$project_record_name THEN
          IF ((project_limit_applies) AND (validation_level > avc$account_level)) THEN
            record_to_update_found := TRUE;
          IFEND;
        ELSE
          IF ((project_member_limit_applies) AND (validation_level > avc$account_level)) THEN
            record_to_update_found := TRUE;
          IFEND;
        IFEND;

{ Unlock the record if will not be used.

        IF NOT record_to_update_found THEN
          avp$unlock_template_file (file_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

      UNTIL record_to_update_found;

{ Get the specified limit field from the record.

      avp$get_field (accum_limit_field_name, data_record, description_record, {work_area=} NIL, field_value,
            type_specification, default_value, descriptive_text, utility_information, status);

    PROCEND get_next_validation_file_entry;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

    IF NOT avp$system_administrator () THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

    IF UPPERBOUND (limit_update_info_array^) > 0 THEN
      sort_total_limit_update_info (limit_update_info_array, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      previous_family_name := limit_update_info_array^ [1].family_name;
    ELSE

{ No limit update information is available so return.

      RETURN;
    IFEND;

    current_entry := 0;
    validation_level := avp$validation_level ();

    high_value_key.account_name := avc$high_value_name;
    high_value_key.project_name := avc$high_value_name;
    high_value_key.user_name := avc$high_value_name;

    field_value_list.field_name := accum_limit_field_name;
    field_value_list.forward := NIL;

    PUSH data_record: [[REP avc$max_template_record_size OF cell]];
    PUSH description_record: [[REP avc$max_template_record_size OF cell]];

{ Process entries until the end of BOTH input sources is found.

    REPEAT

{ Get an entry from the limit update information.

      get_next_update_entry (limit_update_info_array, previous_family_name, family_name, limit_update_key,
            size, current_entry);

{ Don't allow limit updates on the client.

      avp$check_for_served_family (family_name, served_family);
      IF served_family THEN
        osp$set_status_abnormal ('AV', ave$not_allowed_on_client, 'LIMIT UPDATING', status);
        RETURN;
      IFEND;

{ Open the validation file for the family found on the update record.

      avp$open_system_validation_file (family_name, validation_file_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

    /validation_file_open/

      BEGIN

{ Find out which validation records contain the specified limit.

{ Check the user description record.

        get_field_description (accum_limit_field_name, avc$user_record_name, osc$null_name,
              {field_work_area=} NIL, description_record, default_value, type_specification, description,
              field_utility_information, validation_file_information, status);
        IF status.normal THEN
          user_limit_applies := TRUE;
        ELSE
          IF (status.condition = ave$unknown_field) OR (status.condition = ave$field_was_deleted) THEN
            user_limit_applies := FALSE;
            status.normal := TRUE;
          ELSE
            EXIT /validation_file_open/;
          IFEND;
        IFEND;

{ Check the account description record.

        get_field_description (accum_limit_field_name, avc$account_record_name, osc$null_name,
              {field_work_area=} NIL, description_record, default_value, type_specification, description,
              field_utility_information, validation_file_information, status);
        IF status.normal THEN
          account_limit_applies := TRUE;
        ELSE
          IF (status.condition = ave$unknown_field) OR (status.condition = ave$field_was_deleted) THEN
            account_limit_applies := FALSE;
            status.normal := TRUE;
          ELSE
            EXIT /validation_file_open/;
          IFEND;
        IFEND;

{ Check the account member description record.

        get_field_description (accum_limit_field_name, avc$account_member_record_name, osc$null_name,
              {field_work_area=} NIL, description_record, default_value, type_specification, description,
              field_utility_information, validation_file_information, status);
        IF status.normal THEN
          account_member_limit_applies := TRUE;
        ELSE
          IF (status.condition = ave$unknown_field) OR (status.condition = ave$field_was_deleted) THEN
            account_member_limit_applies := FALSE;
            status.normal := TRUE;
          ELSE
            EXIT /validation_file_open/;
          IFEND;
        IFEND;

{ Check the project description record.

        get_field_description (accum_limit_field_name, avc$project_record_name, osc$null_name,
              {field_work_area=} NIL, description_record, default_value, type_specification, description,
              field_utility_information, validation_file_information, status);
        IF status.normal THEN
          project_limit_applies := TRUE;
        ELSE
          IF (status.condition = ave$unknown_field) OR (status.condition = ave$field_was_deleted) THEN
            project_limit_applies := FALSE;
            status.normal := TRUE;
          ELSE
            EXIT /validation_file_open/;
          IFEND;
        IFEND;

{ Check the project member description record.

        get_field_description (accum_limit_field_name, avc$project_member_record_name, osc$null_name,
              {field_work_area=} NIL, description_record, default_value, type_specification, description,
              field_utility_information, validation_file_information, status);
        IF status.normal THEN
          project_member_limit_applies := TRUE;
        ELSE
          IF (status.condition = ave$unknown_field) OR (status.condition = ave$field_was_deleted) THEN
            project_member_limit_applies := FALSE;
            status.normal := TRUE;
          ELSE
            EXIT /validation_file_open/;
          IFEND;
        IFEND;

        IF NOT (user_limit_applies OR account_limit_applies OR account_member_limit_applies OR
              project_limit_applies OR project_member_limit_applies) THEN

{ If the specified limit does not exist on this validation file then start
{ at the end so no updates are attempted.

          validation_file_information.last_key_accessed (1, 31) := avc$high_value_name {account_name} ;
          validation_file_information.last_key_accessed (32, 31) := avc$high_value_name {project_name} ;
          validation_file_information.last_key_accessed (63, 31) := avc$high_value_name {user_name} ;
        ELSEIF ((validation_level = avc$user_level) OR NOT (account_limit_applies OR
              account_member_limit_applies OR project_limit_applies OR project_member_limit_applies)) THEN

{ If the system is running at user level OR the specified limit only applies
{ to user records then start at the first user record.

          validation_file_information.last_key_accessed (1, 31) := avc$high_value_name {account_name} ;
          validation_file_information.last_key_accessed (32, 31) := avc$high_value_name {project_name} ;
          validation_file_information.last_key_accessed (63, 31) := osc$null_name {user_name} ;
        ELSE

{ Otherwise start at the first record on the file.

          validation_file_information.last_key_accessed (1, 31) := osc$null_name {account_name} ;
          validation_file_information.last_key_accessed (32, 31) := osc$null_name {project_name} ;
          validation_file_information.last_key_accessed (63, 31) := osc$null_name {user_name} ;
        IFEND;

{ Get the first validation file entry.

        get_next_validation_file_entry (accum_limit_field_name, data_record, description_record,
              validation_file_key, field_value_list.field_value, validation_file_information, status);
        IF NOT status.normal THEN
          EXIT /validation_file_open/;
        IFEND;

{ Process each validation validation record found until the end of the validation file,
{ Synchronizing the validation file with the updates as each record is processed.

        REPEAT

{ If no update information exists for the validation record then zero out the
{ accumulator for the record and rewrite it.

          IF validation_file_key.value < limit_update_key.value THEN
            field_value_list.field_value.total_accumulation^ := 0;
            avp$rewrite_data_record (validation_file_key.value, TRUE, data_record, description_record,
                  ^field_value_list, validation_file_information, status);
            IF NOT status.normal THEN
              EXIT /validation_file_open/;
            IFEND;

{ Get the next entry from the validation file.


            get_next_validation_file_entry (accum_limit_field_name, data_record, description_record,
                  validation_file_key, field_value_list.field_value, validation_file_information, status);
            IF NOT status.normal THEN
              EXIT /validation_file_open/;
            IFEND;
          ELSEIF validation_file_key.value > limit_update_key.value THEN

{ No validation record exists for this update information.
{ This may be a normal situation (i.e. The file was created by a user from a
{ different family using an account and/or project that do not exist on this
{ family.), or it may be an abnormal situation (i.e. The file may belong to
{ a user who has been deleted from the validation file but his files still
{ exist.).

{ What do we do in this situation.  I guess we emit an error statistic but
{ tell the site that they can deactivate the statistic if they are not
{ concerned with this problem.

{ Get the next entry from the updates.

            get_next_update_entry (limit_update_info_array, previous_family_name, family_name,
                  limit_update_key, size, current_entry);

          ELSE

{ Update the accumulator for the validation record with
{ the amount found on the matching update entry.

            field_value_list.field_value.total_accumulation^ := size;
            avp$rewrite_data_record (validation_file_key.value, TRUE, data_record, description_record,
                  ^field_value_list, validation_file_information, status);
            IF NOT status.normal THEN
              EXIT /validation_file_open/;
            IFEND;

{ Get the next entry from the validation file.

            get_next_validation_file_entry (accum_limit_field_name, data_record, description_record,
                  validation_file_key, field_value_list.field_value, validation_file_information, status);
            IF NOT status.normal THEN
              EXIT /validation_file_open/;
            IFEND;

{ Get the next entry from the updates.

            get_next_update_entry (limit_update_info_array, previous_family_name, family_name,
                  limit_update_key, size, current_entry);

          IFEND;

        UNTIL (limit_update_key.value = high_value_key.value) AND
              (validation_file_key.value = high_value_key.value);

{ The end of the validation file, and the end of the updates
{ for this family have been reached.

      END /validation_file_open/;
      IF NOT status.normal THEN
        avp$close_validation_file (validation_file_information, ignore_status);
        RETURN;
      ELSE
        avp$close_validation_file (validation_file_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

{ family name is set to null name when the end of the update entries is found.

    UNTIL family_name = osc$null_name;

  PROCEND avp$replace_total_limits;
?? TITLE := '    avp$update_eoj_total_limits', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is called at end of job to update the total access limits in the
{ validation file from the statistics facility limit chain information.
{
{ DESIGN:
{
{ To be supplied.
{

  PROCEDURE [XDCL] avp$update_eoj_total_limits
    (VAR status: ost$status);

    VAR
      account_name: avt$account_name,
      ignore_status: ost$status,
      project_name: avt$project_name,
      served_family: boolean,
      user_identification: ost$user_identification,
      validation_file_information: avt$template_file_information,
      validation_level: avt$validation_level,
      validated_limit: ^avt$validated_limit;

?? NEWTITLE := '      update_total_limit', EJECT ??
{
{ PURPOSE:
{
{   This procedure used to update the total access limits in the
{ validation file for the specified limit chain item.
{

    PROCEDURE update_total_limits
      (    validated_limits: ^avt$validated_limit;
           user_name: ost$user_name;
           account_name: avt$account_name;
           project_name: avt$project_name;
       VAR validation_file_information: avt$template_file_information;
       VAR status: ost$status);

      VAR
        key: avt$validation_key;

?? NEWTITLE := '        update_validation_record', EJECT ??
{
{ PURPOSE:
{
{   This procedure used to update the total access limit in the
{ specified validation record for the specified limit chain item.
{

      PROCEDURE update_validation_record
        (    validated_limits: ^avt$validated_limit;
         VAR key: avt$validation_key;
         VAR validation_file_information: avt$template_file_information;
         VAR status: ost$status);

        VAR
          current_field_value_entry: ^avt$field_value_list_entry,
          current_validated_limit: ^avt$validated_limit,
          data_record: ^avt$template_file_record,
          data_record_size: 0 .. avc$max_template_record_size,
          default_value: avt$field_value,
          description_record: ^avt$template_file_record,
          description_record_size: 0 .. avc$max_template_record_size,
          descriptive_text: ^avt$descriptive_text,
          description_record_name: ost$name,
          field_count: avt$field_count,
          utility_information: ^avt$utility_information,
          field_value: avt$field_value,
          field_value_list: ^avt$field_value_list_entry,
          limit: sft$limit,
          type_specification: avt$type_specification;

        status.normal := TRUE;

        PUSH data_record: [[REP avc$max_template_record_size OF cell]];
        RESET data_record;
        PUSH description_record: [[REP avc$max_template_record_size OF cell]];
        RESET description_record;

        field_value_list := NIL;

        avp$read_data_record (key.value, avc$update_access, FALSE, data_record, data_record_size,
              description_record, description_record_size, description_record_name, field_count,
              validation_file_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        current_validated_limit := validated_limits;

      /process_validated_limits/

        WHILE current_validated_limit <> NIL DO

{ Get the current field value.

          IF (current_validated_limit^.kind = avc$accumulating_limit_kind) AND
                current_validated_limit^.total_limit_applies THEN
            avp$get_field (current_validated_limit^.field_name, data_record, description_record,
                  {work_area=} NIL, field_value, type_specification, default_value, descriptive_text,
                  utility_information, status);
            IF NOT status.normal THEN
              IF (status.condition = ave$unknown_field) OR (status.condition = ave$field_was_deleted) THEN
                status.normal := TRUE;
                current_validated_limit := current_validated_limit^.forward;
                CYCLE /process_validated_limits/;
              IFEND;
              EXIT /process_validated_limits/;
            IFEND;

            IF type_specification.total_limit_applies^ THEN
              sfp$get_job_limit (current_validated_limit^.limit_name, limit, status);
              IF NOT status.normal THEN
                EXIT /process_validated_limits/;
              IFEND;
              IF field_value_list = NIL THEN
                PUSH field_value_list;
                current_field_value_entry := field_value_list;
              ELSE
                PUSH current_field_value_entry^.forward;
                current_field_value_entry := current_field_value_entry^.forward;
              IFEND;
              current_field_value_entry^.forward := NIL;
              current_field_value_entry^.field_name := current_validated_limit^.field_name;
              current_field_value_entry^.field_value := field_value;
              current_field_value_entry^.field_value.total_accumulation^ :=
                    current_field_value_entry^.field_value.total_accumulation^ +
                    (limit.accumulator - current_validated_limit^.initial_value);
              IF current_field_value_entry^.field_value.total_accumulation^ < 0 THEN
                current_field_value_entry^.field_value.total_accumulation^ := 0;
              IFEND;
            IFEND;
          IFEND;

          current_validated_limit := current_validated_limit^.forward;
        WHILEND /process_validated_limits/;

        IF status.normal AND (field_value_list <> NIL) THEN
          avp$rewrite_data_record (key.value, TRUE, data_record, description_record, field_value_list,
                validation_file_information, status);
        ELSE
          avp$unlock_template_file (validation_file_information, ignore_status);
        IFEND;

      PROCEND update_validation_record;
?? OLDTITLE, EJECT ??
      status.normal := TRUE;

      key.account_name := avc$high_value_name;
      key.project_name := avc$high_value_name;
      key.user_name := user_name;

      update_validation_record (validated_limits, key, validation_file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          status.normal := TRUE;
        ELSE
          RETURN;
        IFEND;
      IFEND;

      IF validation_level > avc$user_level THEN

{ Update the account limit information.

        key.account_name := account_name;
        key.project_name := osc$null_name;
        key.user_name := osc$null_name;
        update_validation_record (validated_limits, key, validation_file_information, status);
        IF NOT status.normal THEN
          IF status.condition = ave$unknown_record THEN
            status.normal := TRUE;
          ELSE
            RETURN;
          IFEND;
        IFEND;

{ Update the account member limit information.

        key.account_name := account_name;
        key.project_name := osc$null_name;
        key.user_name := user_name;
        update_validation_record (validated_limits, key, validation_file_information, status);
        IF NOT status.normal THEN
          IF status.condition = ave$unknown_record THEN
            key.user_name := '$PUBLIC                        ';
            update_validation_record (validated_limits, key, validation_file_information, status);
            IF status.condition = ave$unknown_record THEN
              status.normal := TRUE;
            IFEND;
          ELSE
            RETURN;
          IFEND;
        IFEND;
      IFEND;

      IF validation_level > avc$account_level THEN

{ Update the project limit information.

        key.account_name := account_name;
        key.project_name := project_name;
        key.user_name := osc$null_name;
        update_validation_record (validated_limits, key, validation_file_information, status);
        IF NOT status.normal THEN
          IF status.condition = ave$unknown_record THEN
            status.normal := TRUE;
          ELSE
            RETURN;
          IFEND;
        IFEND;

{ Update the project member limit information.

        key.account_name := account_name;
        key.project_name := project_name;
        key.user_name := user_name;
        update_validation_record (validated_limits, key, validation_file_information, status);
        IF NOT status.normal THEN
          IF status.condition = ave$unknown_record THEN
            key.user_name := '$PUBLIC                        ';
            update_validation_record (validated_limits, key, validation_file_information, status);
            IF NOT status.normal THEN
              IF status.condition = ave$unknown_record THEN
                status.normal := TRUE;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;

    PROCEND update_total_limits;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

    validation_level := avp$validation_level ();

{ Get executing user identification.

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

{ Get executing account and project names.

    pmp$get_account_project (account_name, project_name, status);

{ Don't update the validation file if this is a served family.

    avp$check_for_served_family (user_identification.family, served_family);
    IF served_family THEN
      RETURN;
    IFEND;

    avp$open_system_validation_file (user_identification.family, validation_file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    update_total_limits (avv$validated_limits, user_identification.user, account_name, project_name,
          validation_file_information, status);
    IF NOT status.normal THEN
      avp$close_validation_file (validation_file_information, ignore_status);
    ELSE
      avp$close_validation_file (validation_file_information, status);
    IFEND;

  PROCEND avp$update_eoj_total_limits;

?? TITLE := '    avp$validate_job', EJECT ??
*copyc avh$validate_job
{ DESIGN:
{
{   This interface opens the validation file and then verifies access for the
{ specified user.  An optional list of items to validate is input.
{
{ The following items are always validated:
{   The user is validated for access to the family.
{   Account membership if running at account level.
{   Account or Project membership if running at project level.
{ The following items are optional validations:
{   Password. (In it's encrypted form)
{   Job Class.
{   Job execution ring.
{   Job limits.
{   Required capabilites.
{
{   The master catalog for the user is created if it does not already exist.
{
{   Job limits from the validation file are extracted and stored in memory
{ for later use by the statistics facility for limit setup, and logout for
{ total limit updates.

  PROCEDURE [XDCL] avp$validate_job
    (    user_name: ost$user_name;
         family_name: ost$family_name;
         account: avt$account_name;
         project: avt$project_name;
         validation_attributes: ^avt$validation_items;
     VAR status: ost$status);

    TYPE
      limit_item = record
        limit_name: ost$name,
        user_specified: boolean,
        job_maximum_limit: sft$counter,
        forward: ^limit_item,
      recend;

    VAR
      account_member_exists: boolean,
      account_name: avt$account_name,
      block: ^clt$block,
      caller_authority: avt$validation_authority,
      capability: boolean,
      current_date_time: ost$date_time,
      current_limit_item: ^limit_item,
      default_value: avt$field_value,
      description_record_name: ost$name,
      descriptive_text: ^avt$descriptive_text,
      default_name: jmt$job_class_name,
      field_count: avt$field_count,
      field_value: avt$field_value,
      file_information: avt$template_file_information,
      found_job_class: boolean,
      ignore_status: ost$status,
      increment: pmt$time_increment,
      index: integer,
      item_index: integer,
      job_class: jmt$job_class,
      job_maximum: sft$counter,
      key: avt$validation_key,
      limit_field_names: ^array [1 .. * ] of ost$name,
      limit_item_list: ^limit_item,
      path: array [1 .. 4] of pft$name,
      project_exists: boolean,
      project_member_exists: boolean,
      project_name: avt$project_name,
      temp_login_password: avt$password,
      type_specification: avt$type_specification,
      utility_information: ^avt$utility_information,
      validated_limit_item: ^avt$validated_limit;

?? NEWTITLE := '      create_validated_limit', EJECT ??
{
{ PURPOSE:
{
{   This procedure adds a limit from the validation file to a validated limit
{ chain.
{

    PROCEDURE create_validated_limit
      (    field_name: ost$name;
       VAR type_specification: avt$type_specification;
       VAR field_value: avt$field_value);

      VAR
        current_limit: ^avt$validated_limit,
        job_maximum: sft$counter,
        validated_limit: ^avt$validated_limit;

{ Retrieve the job maximum limit value.  If total limits apply for this limit
{ and the amount of resource left before hitting the total limit is less than
{ the job maximum then set the job maximum to the amount of resource left.

      IF field_name = avc$permanent_file_space_limit THEN
        PUSH type_specification.job_limits_apply;
        type_specification.job_limits_apply^ := TRUE;
        PUSH field_value.job_maximum_limit;
        PUSH field_value.job_warning_limit;
        field_value.job_maximum_limit^ := field_value.total_limit^;
        field_value.job_warning_limit^ := field_value.total_limit^;
      IFEND;

      IF (((type_specification.kind = avc$accumulating_limit_kind) AND
            (type_specification.job_limits_apply^)) OR (type_specification.kind = avc$limit_kind)) THEN
        IF type_specification.kind = avc$accumulating_limit_kind THEN
          job_maximum := field_value.job_maximum_limit^;
          IF ((type_specification.total_limit_applies^) AND (type_specification.total_limit_stops_login^) AND
                (field_value.total_limit^ <> sfc$unlimited)) THEN
            IF ((field_value.total_limit^) - (field_value.total_accumulation^)) < job_maximum THEN
              job_maximum := ((field_value.total_limit^) - (field_value.total_accumulation^));
            IFEND;
          IFEND;
        IFEND;

{ Allocate space for the limit and place it in the beginning of the limit
{ chain.

        ALLOCATE validated_limit IN osv$task_shared_heap^;

        validated_limit^.kind := type_specification.kind;
        validated_limit^.field_name := field_name;
        validated_limit^.limit_name := type_specification.limit_name^;
        IF validated_limit^.limit_name = avc$cp_time_limit_name THEN
          validated_limit^.limit_name := avc$cpu_time_limit_name;
        IFEND;
        validated_limit^.forward := NIL;

        CASE field_value.kind OF

{ Assign limit values to the limit chain entry.

        = avc$accumulating_limit_kind =
          validated_limit^.statistic_codes := type_specification.limit_update_statistics;
          validated_limit^.job_warning_limit := field_value.job_warning_limit^;
          validated_limit^.job_maximum_limit := field_value.job_maximum_limit^;
          IF (type_specification.limit_update_statistics <> NIL) OR
             (validated_limit^.limit_name = avc$cpu_time_limit_name) OR
             (validated_limit^.limit_name = avc$sru_limit_name) THEN
            validated_limit^.enforcement := sfc$accumulation_enforcement;
          ELSE
            validated_limit^.enforcement := sfc$other_enforcement;
          IFEND;
          validated_limit^.initial_value := 0;
          IF validated_limit^.limit_name = avc$task_limit_name THEN
            validated_limit^.initial_value := 1;
          IFEND;
          IF validated_limit^.limit_name = avc$pfs_limit_name THEN
            validated_limit^.initial_value := field_value.total_accumulation^;
            IF validated_limit^.initial_value < 0 THEN
              validated_limit^.initial_value := 0;
            IFEND;
          ELSE
            IF job_maximum < field_value.job_warning_limit^ THEN
              validated_limit^.job_warning_limit := job_maximum;
            IFEND;
            IF job_maximum < field_value.job_maximum_limit^ THEN
              validated_limit^.job_maximum_limit := job_maximum;
            IFEND;
          IFEND;
          validated_limit^.total_limit_applies := type_specification.total_limit_applies^;
        = avc$limit_kind =
          validated_limit^.job_maximum_limit := field_value.limit_value^;
        ELSE
          ;
        CASEND;

{ Insert the limit entry at the front of the limit chain.

        IF avv$validated_limits = NIL THEN
          avv$validated_limits := validated_limit;
        ELSE
          current_limit := avv$validated_limits;
          WHILE current_limit^.forward <> NIL DO
            current_limit := current_limit^.forward;
          WHILEND;
          current_limit^.forward := validated_limit;
        IFEND;
      IFEND;

    PROCEND create_validated_limit;

?? TITLE := '      change_validated_limit', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to to vote down the allowed limit value with limits
{ from the account and project level validation records.
{

    PROCEDURE change_validated_limit
      (    field_name: ost$name;
           field_value: avt$field_value;
           type_specification: avt$type_specification);

      VAR
        current_limit: ^avt$validated_limit,
        job_maximum: sft$counter,
        validated_limit: ^avt$validated_limit;

{ Permanent file space limits are not voted down.

      IF field_name = avc$permanent_file_space_limit THEN
        RETURN;
      IFEND;

{ If the total limit stops login for this limit then get the amount
{ of resource left before hitting the total limit.

      IF (type_specification.total_limit_stops_login^) AND (field_value.total_limit^ <> sfc$unlimited) THEN
        job_maximum := ((field_value.total_limit^) - (field_value.total_accumulation^));

        current_limit := avv$validated_limits;

{ If a user level limit does not exist for this limit then the lower level
{ limit is ignored.

      /find_validated_limit/
        WHILE current_limit <> NIL DO
          IF current_limit^.field_name = field_name THEN
            CASE current_limit^.kind OF

{ Reassign the job limit values if lower than the current value.

            = avc$accumulating_limit_kind =
              IF job_maximum < current_limit^.job_warning_limit THEN
                current_limit^.job_warning_limit := job_maximum;
              IFEND;
              IF job_maximum < current_limit^.job_maximum_limit THEN
                current_limit^.job_maximum_limit := job_maximum;
              IFEND;
              IF type_specification.total_limit_applies^ THEN
                current_limit^.total_limit_applies := TRUE;
              IFEND;
              EXIT /find_validated_limit/;
            ELSE
              ;
            CASEND;
          IFEND;
          current_limit := current_limit^.forward;
        WHILEND /find_validated_limit/;
      IFEND;

    PROCEND change_validated_limit;
?? OLDTITLE, EJECT ??

    status.normal := TRUE;

    avv$validated_limits := NIL;
    limit_item_list := NIL;

{ Store the validation information for this user in memory.

    account_name := account;
    project_name := project;
    avp$store_validation_info (family_name, user_name, account_name, project_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Store the account and project.

    avv$account_name := account_name;
    avv$project_name := project_name;

{ Skip the check for an expired password in the system job.

    IF NOT jmp$system_job () THEN

{ Retrieve the login password value for this user.

      avp$get_field (avc$login_password, avv$user_data_record, avv$user_description_record, {work_area=} NIL,
            field_value, type_specification, default_value, descriptive_text, utility_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

{ Verify that the user's password has not expired.

      IF field_value.login_password_exp_date^.year <> avc$no_expiration_date THEN
        pmp$get_compact_date_time (current_date_time, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        pmp$compute_date_time_increment (current_date_time, field_value.login_password_exp_date^, increment,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        IF (increment.year < 0) OR (increment.month < 0) OR (increment.day < 0) OR (increment.hour < 0) OR
              (increment.minute < 0) OR (increment.second < 0) OR (increment.millisecond < 0) THEN
          osp$set_status_condition (ave$bad_user_validation_info, status);
          RETURN;
        IFEND;
      IFEND;
    IFEND;

{ If executing in the system job, then determine whether the job has been
{ validated for system_operation or removable_media_operation.

    IF jmp$system_job () THEN
      avv$validated_sou_capabilities := $avt$conditional_capabilities [];

      avp$get_capability (avc$removable_media_operation, avc$user, capability, status);
      IF status.normal THEN
        IF capability THEN
          avv$validated_sou_capabilities := avv$validated_sou_capabilities
                + $avt$conditional_capabilities [avc$cc_removable_media_operator];
        IFEND;
      ELSEIF status.condition <> ave$unknown_field THEN
        RETURN;
      IFEND;

      avp$get_capability (avc$system_operation, avc$user, capability, status);
      IF status.normal THEN
        IF capability THEN
          avv$validated_sou_capabilities := avv$validated_sou_capabilities
                + $avt$conditional_capabilities [avc$cc_system_operator];
        IFEND;
      ELSEIF status.condition <> ave$unknown_field THEN
        RETURN;
      IFEND;

{ Otherwise, clear the active_capabilities field in all blocks on the block
{ stack and re-evaluate the PF subsystem's administrator status for the
{ executing task.

    ELSE
      clp$find_current_block (block);
      WHILE block <> NIL DO
        block^.active_capabilities := $avt$conditional_capabilities [];
        block := block^.previous_block;
      WHILEND;
      pfp$reset_administrator_status;
    IFEND;

    avp$get_field (avc$ring_privileges, avv$user_data_record, avv$user_description_record, {work_area=} NIL,
      field_value, type_specification, default_value, descriptive_text, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    avv$minimum_ring := field_value.minimum_ring^;
    avv$nominal_ring := field_value.nominal_ring^;

    IF validation_attributes <> NIL THEN
      FOR item_index := 1 TO UPPERBOUND (validation_attributes^) DO
        CASE validation_attributes^ [item_index].key OF

{ Validate the specified job class.

        = avc$job_class_name_key =

{ Retrieve the user's valid job class list.

          avp$get_field (avc$job_class, avv$user_data_record, avv$user_description_record, {work_area=} NIL,
                field_value, type_specification, default_value, descriptive_text, utility_information,
                status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

{ Verify that the user is valid for the requested job class.

          validate_job_class (field_value, validation_attributes^ [item_index].job_class_name,
                found_job_class);
          IF NOT found_job_class THEN
            osp$set_status_abnormal ('AV', ave$bad_job_class,
                  validation_attributes^ [item_index].job_class_name, status);
            RETURN;
          IFEND;

{ Validate the specified job execution ring.

        = avc$job_execution_ring_key =

{ Verify that the user is valid to run at the specified ring.

          IF validation_attributes^ [item_index].job_execution_ring < avv$minimum_ring THEN
            osp$set_status_abnormal ('AV', ave$bad_ring, '', status);
            RETURN;
          IFEND;

{ Validate the specified job limit.

        = avc$job_limit_key =

{ Save the specified job limit for later validation.

          IF limit_item_list = NIL THEN
            PUSH current_limit_item;
            limit_item_list := current_limit_item;
          ELSE
            PUSH current_limit_item^.forward;
            current_limit_item := current_limit_item^.forward;
          IFEND;
          current_limit_item^.limit_name := validation_attributes^ [item_index].limit_name;
          current_limit_item^.user_specified := validation_attributes^ [item_index].user_specified;
          current_limit_item^.job_maximum_limit := validation_attributes^ [item_index].job_maximum;
          current_limit_item^.forward := NIL;

{ Validate the specified password.

        = avc$password_key =

{ Retrieve the user's login password value.

          avp$get_field (avc$login_password, avv$user_data_record, avv$user_description_record,
                {work_area=} NIL, field_value, type_specification, default_value, descriptive_text,
                utility_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

{ Verify the specfied login password value.

          IF field_value.login_password^.value <> validation_attributes^ [item_index].password THEN
            osp$set_status_condition (ave$bad_user_validation_info, status);
            RETURN;
          IFEND;

{ Validate the specified required capability.

        = avc$required_capability_key =

{ Retrieve the specified capability.

          avp$get_field (validation_attributes^ [item_index].required_capability, avv$user_data_record,
                avv$user_description_record, {work_area=} NIL, field_value, type_specification, default_value,
                descriptive_text, utility_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

{ Verify that the user has the specified required capability.

          IF NOT field_value.capability^ THEN
            osp$set_status_abnormal ('AV', ave$missing_required_capability,
                  validation_attributes^ [item_index].required_capability, status);
            RETURN;
          IFEND;
        ELSE
          ;
        CASEND;
      FOREND;
    IFEND;

{ Check limits if not in the system job.

    IF NOT jmp$system_job () THEN

{ User Limit Checking

{ Retrieve a list of all accumulating limit and limit type fields from the user record.

      PUSH limit_field_names: [1 .. avc$maximum_field_count];
      avp$get_field_names ($avt$field_kind_set [avc$accumulating_limit_kind, avc$limit_kind], FALSE,
            avv$user_description_record, limit_field_names^, field_count, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

{ Check each user limit.

      FOR index := 1 TO field_count DO
        avp$get_field (limit_field_names^ [index], avv$user_data_record, avv$user_description_record,
              {work_area=} NIL, field_value, type_specification, default_value, descriptive_text,
              utility_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ Verify that the user's total limit has not been exceeded.

        IF ((type_specification.kind = avc$accumulating_limit_kind) AND
              (type_specification.total_limit_applies^) AND (type_specification.total_limit_stops_login^) AND
              (field_value.total_limit^ <> sfc$unlimited) AND (field_value.total_accumulation^ >=
              field_value.total_limit^)) THEN
          osp$set_status_condition (ave$bad_user_validation_info, status);
          RETURN;
        IFEND;

{ Add the limit to the validated limit chain.

        create_validated_limit (limit_field_names^ [index], type_specification, field_value);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      FOREND;

{ Account Limit Checking (only if validation level is account or project)

      IF avv$account_data_record <> NIL THEN

{ Retrieve a list of all accumulating limit fields from the account record.

        PUSH limit_field_names: [1 .. avc$maximum_field_count];
        avp$get_field_names ($avt$field_kind_set [avc$accumulating_limit_kind], FALSE,
              avv$account_description_record, limit_field_names^, field_count, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ Check each account limit.

        FOR index := 1 TO field_count DO
          avp$get_field (limit_field_names^ [index], avv$account_data_record, avv$account_description_record,
                {work_area=} NIL, field_value, type_specification, default_value, descriptive_text,
                utility_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

{ Verify that the account's total limit has not been exceeded.

          IF ((type_specification.kind = avc$accumulating_limit_kind) AND
                (type_specification.total_limit_applies^) AND (type_specification.
                total_limit_stops_login^) AND (field_value.total_limit^ <> sfc$unlimited) AND
                (field_value.total_accumulation^ >= field_value.total_limit^)) THEN
            osp$set_status_condition (ave$bad_user_validation_info, status);
            RETURN;
          IFEND;

{ Vote down the user job limit values with those from the account.

          change_validated_limit (limit_field_names^ [index], field_value, type_specification);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        FOREND;
      IFEND;

{ Account Member Limit Checking (only if validation level is account or project)

      IF avv$account_member_data_record <> NIL THEN

{ Retrieve a list of all accumulating limit fields from the account member record.

        PUSH limit_field_names: [1 .. avc$maximum_field_count];
        avp$get_field_names ($avt$field_kind_set [avc$accumulating_limit_kind], FALSE,
              avv$account_member_desc_record, limit_field_names^, field_count, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ Check each account member limit.

        FOR index := 1 TO field_count DO
          avp$get_field (limit_field_names^ [index], avv$account_member_data_record,
                avv$account_member_desc_record, {work_area=} NIL, field_value, type_specification,
                default_value, descriptive_text, utility_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

{ Verify that the account member's total limit has not been exceeded.

          IF ((type_specification.kind = avc$accumulating_limit_kind) AND
                (type_specification.total_limit_applies^) AND (type_specification.
                total_limit_stops_login^) AND (field_value.total_limit^ <> sfc$unlimited) AND
                (field_value.total_accumulation^ >= field_value.total_limit^)) THEN
            osp$set_status_condition (ave$bad_user_validation_info, status);
            RETURN;
          IFEND;

{ Vote down the user job limit values with those from the account member.

          change_validated_limit (limit_field_names^ [index], field_value, type_specification);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        FOREND;
      IFEND;

{ Project Limit Checking (only if validation level is project)

      IF avv$project_data_record <> NIL THEN

{ Retrieve a list of all accumulating limit fields from the project record.

        PUSH limit_field_names: [1 .. avc$maximum_field_count];
        avp$get_field_names ($avt$field_kind_set [avc$accumulating_limit_kind], FALSE,
              avv$project_description_record, limit_field_names^, field_count, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ Check each project limit.

        FOR index := 1 TO field_count DO
          avp$get_field (limit_field_names^ [index], avv$project_data_record, avv$project_description_record,
                {work_area=} NIL, field_value, type_specification, default_value, descriptive_text,
                utility_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

{ Verify that the project's total limit has not been exceeded.

          IF ((type_specification.kind = avc$accumulating_limit_kind) AND
                (type_specification.total_limit_applies^) AND (type_specification.
                total_limit_stops_login^) AND (field_value.total_limit^ <> sfc$unlimited) AND
                (field_value.total_accumulation^ >= field_value.total_limit^)) THEN
            osp$set_status_condition (ave$bad_user_validation_info, status);
            RETURN;
          IFEND;

{ Vote down the user job limit values with those from the project.

          change_validated_limit (limit_field_names^ [index], field_value, type_specification);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        FOREND;
      IFEND;

{ Project Member Limit Checking (only if validation level is project)

      IF avv$project_member_data_record <> NIL THEN

{ Retrieve a list of all accumulating limit fields from the project member record.

        PUSH limit_field_names: [1 .. avc$maximum_field_count];
        avp$get_field_names ($avt$field_kind_set [avc$accumulating_limit_kind], FALSE,
              avv$project_member_desc_record, limit_field_names^, field_count, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ Check each project member limit.

        FOR index := 1 TO field_count DO
          avp$get_field (limit_field_names^ [index], avv$project_member_data_record,
                avv$project_member_desc_record, {work_area=} NIL, field_value, type_specification,
                default_value, descriptive_text, utility_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

{ Verify that the project member's total limit has not been exceeded.

          IF ((type_specification.kind = avc$accumulating_limit_kind) AND
                (type_specification.total_limit_applies^) AND (type_specification.
                total_limit_stops_login^) AND (field_value.total_limit^ <> sfc$unlimited) AND
                (field_value.total_accumulation^ >= field_value.total_limit^)) THEN
            osp$set_status_condition (ave$bad_user_validation_info, status);
            RETURN;
          IFEND;

{ Vote down the user job limit values with those from the project member.

          change_validated_limit (limit_field_names^ [index], field_value, type_specification);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        FOREND;
      IFEND;

{ Check to see if the user has specified a job maximum for any limits.

      current_limit_item := limit_item_list;

    /find_specified_job_maximum/
      WHILE current_limit_item <> NIL DO

        validated_limit_item := avv$validated_limits;

      /find_validated_job_maximum/
        WHILE validated_limit_item <> NIL DO

{ The user may not specify a job maximum that is greater than validated for.

          IF current_limit_item^.limit_name = validated_limit_item^.limit_name THEN
            IF ((current_limit_item^.user_specified) AND (validated_limit_item^.job_maximum_limit <
                  current_limit_item^.job_maximum_limit)) THEN
              osp$set_status_abnormal ('AV', ave$bad_user_specified_job_max, current_limit_item^.limit_name,
                    status);
              RETURN;

{ If the specified job maximum is less than current reset it.

            ELSEIF current_limit_item^.job_maximum_limit < validated_limit_item^.job_maximum_limit THEN
              validated_limit_item^.job_maximum_limit := current_limit_item^.job_maximum_limit;
              IF ((validated_limit_item^.kind = avc$accumulating_limit_kind) AND
                    (current_limit_item^.job_maximum_limit < validated_limit_item^.job_warning_limit)) THEN
                validated_limit_item^.job_warning_limit := current_limit_item^.job_maximum_limit;
              IFEND;
            IFEND;
            EXIT /find_validated_job_maximum/;
          IFEND;

          validated_limit_item := validated_limit_item^.forward;
        WHILEND /find_validated_job_maximum/;

        current_limit_item := current_limit_item^.forward;
      WHILEND /find_specified_job_maximum/;
    IFEND;

  PROCEND avp$validate_job;
?? OLDTITLE ??
?? NEWTITLE := 'avp$validate_nqs_user', EJECT ??
*copyc avh$validate_nqs_user

  PROCEDURE [XDCL, #GATE] avp$validate_nqs_user
    (    user: ost$user_name;
         family: ost$family_name;
         account: avt$account_name;
         project: avt$project_name;
         unix_username: string (* <= 15);
         ring: ost$ring;
     VAR status: ost$status);

    VAR
      validation_attributes: ^avt$validation_items;

    status.normal := TRUE;

    PUSH validation_attributes: [1 .. 3];
    validation_attributes^ [1].key := avc$unix_username_key;
    validation_attributes^ [1].unix_username := unix_username;
    validation_attributes^ [2].key := avc$account_project_key;
    validation_attributes^ [2].account_name := account;
    validation_attributes^ [2].project_name := project;
    validation_attributes^ [3].key := avc$job_execution_ring_key;
    validation_attributes^ [3].job_execution_ring := ring;

    avp$prevalidate_job (user, family, validation_attributes, {default_attributes =} NIL, status);

  PROCEND avp$validate_nqs_user;

?? OLDTITLE ??
?? NEWTITLE := 'avp$validate_user', EJECT ??

{
{ PURPOSE:
{
{   This interface validates a family user password account project combination.
{
  PROCEDURE [XDCL, #GATE] avp$validate_user
    (    user: ost$user_name;
         family: ost$family_name;
         password: avt$password;
         account: avt$account_name;
         project: avt$project_name;
     VAR status: ost$status);

    VAR
      validation_attributes: ^avt$validation_items;

    status.normal := TRUE;

    PUSH validation_attributes: [1 .. 2];
    validation_attributes^ [1].key := avc$password_key;
    validation_attributes^ [1].password := password;
    validation_attributes^ [2].key := avc$account_project_key;
    validation_attributes^ [2].account_name := account;
    validation_attributes^ [2].project_name := project;

    avp$prevalidate_job (user, family, validation_attributes, {default_attributes =} NIL, status);

  PROCEND avp$validate_user;

?? TITLE := '    avp$validation_level', EJECT ??
{
{ PURPOSE:
{
{   This interface returns the current system validation level.
{
  FUNCTION [XDCL, #GATE] avp$validation_level: avt$validation_level;

    IF avv$validation_level = $INTEGER (avc$user_level) THEN
      avp$validation_level := avc$user_level;
    ELSEIF avv$validation_level = $INTEGER (avc$account_level) THEN
      avp$validation_level := avc$account_level;
    ELSE
      avp$validation_level := avc$project_level;
    IFEND;

  FUNCEND avp$validation_level;
?? OLDTITLE ??
?? TITLE := '  File server interfaces' ??
?? NEWTITLE := '    avp$server_prevalidate_job', EJECT ??
{
{ PURPOSE:
{
{   This interfaces is used to prevalidate a job for access to NOS/VE
{ on the server on behalf of a client.
{
  PROCEDURE [XDCL] avp$server_prevalidate_job
    (VAR p_params_received_from_client: dft$p_receive_parameters;
     VAR p_data_received_from_client: dft$p_receive_data;
     VAR p_params_to_send_to_client: dft$p_send_parameters;
     VAR p_data_to_send_to_client: dft$p_send_data;
     VAR params_size_to_send_to_client: dft$send_parameter_size;
     VAR data_size_to_send_to_client: dft$send_data_size;
     VAR status: ost$status);

    VAR
      default_attributes: ^avt$validation_items,
      family_name: ost$family_name,
      job_class_list: ^avt$name_list,
      labeled_names_work_area: ^seq (*),
      user_name: ost$user_name,
      validation_attributes: ^avt$validation_items,
      validation_level: avt$validation_level;

?? NEWTITLE := '      extract_info_sent_from_client', EJECT ??
    PROCEDURE extract_info_sent_from_client
      (VAR p_params_received_from_client: dft$p_receive_parameters;
       VAR p_data_received_from_client: dft$p_receive_data;
       VAR validation_level: avt$validation_level;
       VAR user_name: ost$user_name;
       VAR family_name: ost$family_name;
       VAR validation_attributes: ^avt$validation_items;
       VAR default_attributes: ^avt$validation_items;
       VAR job_class_list: ^avt$name_list;
       VAR labeled_names_work_area: ^seq (*));

      VAR
        item_index: integer,
        server_prevalidate_job_input: ^avt$server_prevalidate_job_in;

      NEXT server_prevalidate_job_input IN p_params_received_from_client;
      validation_level := server_prevalidate_job_input^.validation_level;
      user_name := server_prevalidate_job_input^.user_name;
      family_name := server_prevalidate_job_input^.family_name;
      IF server_prevalidate_job_input^.number_of_val_attributes > 0 THEN
        NEXT validation_attributes: [1 .. server_prevalidate_job_input^.number_of_val_attributes]
              IN p_params_received_from_client;
      ELSE
        validation_attributes := NIL;
      IFEND;
      IF server_prevalidate_job_input^.number_of_def_attributes > 0 THEN
        NEXT default_attributes: [1 .. server_prevalidate_job_input^.number_of_def_attributes]
              IN p_params_received_from_client;
        FOR item_index := 1 TO server_prevalidate_job_input^.number_of_def_attributes DO
          IF default_attributes^ [item_index].key = avc$valid_job_classes_key THEN
            default_attributes^ [item_index].job_classes := job_class_list;
          ELSEIF default_attributes^ [item_index].key = avc$labeled_names_key THEN
            default_attributes^ [item_index].work_area := labeled_names_work_area;
          IFEND;
        FOREND;
      ELSE
        default_attributes := NIL;
      IFEND;

    PROCEND extract_info_sent_from_client;
?? TITLE := '      build_info_to_send_to_client', EJECT ??
    PROCEDURE build_info_to_send_to_client
      (    default_attributes: ^avt$validation_items;
       VAR p_params_to_send_to_client: dft$p_send_parameters;
       VAR p_data_to_send_to_client: dft$p_send_data;
       VAR params_size_to_send_to_client: dft$send_parameter_size;
       VAR data_size_to_send_to_client: dft$send_data_size);

    VAR
      index: integer,
      index2: integer,
      item_index: integer,
      label: ^ost$name,
      name: ^ost$name,
      number_of_def_attributes: integer,
      number_of_labeled_names: ^integer,
      number_of_names: ^integer,
      send_default_attributes: ^avt$validation_items,
      send_valid_job_classes: ^array [1 .. * ] of ost$name;

    params_size_to_send_to_client := 0;
    data_size_to_send_to_client := 0;

{ Return the default attributes.

    IF default_attributes <> NIL THEN
      number_of_def_attributes := UPPERBOUND (default_attributes^);
      IF number_of_def_attributes > 0 THEN
        NEXT send_default_attributes: [1 .. number_of_def_attributes] IN p_params_to_send_to_client;
        FOR item_index := 1 TO number_of_def_attributes DO
          send_default_attributes^ [item_index] := default_attributes^ [item_index];
          IF send_default_attributes^ [item_index].key = avc$valid_job_classes_key THEN
            NEXT send_valid_job_classes: [1 .. UPPERBOUND (send_default_attributes^ [item_index].
                  job_classes^)] IN p_data_to_send_to_client;
            FOR index := 1 TO UPPERBOUND (send_valid_job_classes^) DO
              send_valid_job_classes^ [index] := default_attributes^ [item_index].job_classes^ [index];
            FOREND;
          ELSEIF send_default_attributes^ [item_index].key = avc$labeled_names_key THEN
            NEXT number_of_labeled_names IN p_data_to_send_to_client;
            number_of_labeled_names^ := UPPERBOUND (default_attributes^ [item_index].labeled_names^);
            FOR index := 1 TO number_of_labeled_names^ DO
              NEXT label IN p_data_to_send_to_client;
              label^ := default_attributes^ [item_index].labeled_names^ [index].label^;
              NEXT number_of_names IN p_data_to_send_to_client;
              number_of_names^ := UPPERBOUND (default_attributes^ [item_index].labeled_names^ [index].names^);
              FOR index2 := 1 TO number_of_names^ DO
                NEXT name IN p_data_to_send_to_client;
                name^ := default_attributes^ [item_index].labeled_names^ [index].names^ [index2];
              FOREND;
            FOREND;
          IFEND;
        FOREND;
      IFEND;
    IFEND;

    params_size_to_send_to_client := i#current_sequence_position (p_params_to_send_to_client);
    data_size_to_send_to_client := i#current_sequence_position (p_data_to_send_to_client);

  PROCEND build_info_to_send_to_client;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

    PUSH job_class_list: [1 .. avc$maximum_name_list_size];
    PUSH labeled_names_work_area: [[REP avc$max_template_record_size OF cell]];
    RESET labeled_names_work_area;
    extract_info_sent_from_client (p_params_received_from_client, p_data_received_from_client,
          validation_level, user_name, family_name, validation_attributes, default_attributes,
          job_class_list, labeled_names_work_area);

    prevalidate_job (validation_level, user_name, family_name, validation_attributes, default_attributes,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    build_info_to_send_to_client (default_attributes, p_params_to_send_to_client, p_data_to_send_to_client,
          params_size_to_send_to_client, data_size_to_send_to_client);

  PROCEND avp$server_prevalidate_job;
?? OLDTITLE ??
?? TITLE := '  Interfaces to create validation records' ??
?? NEWTITLE := '    avp$create_account_member_rec', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to put an account member record into the validation
{ file, and stores the record for subsequent changing of the field values
{ within the record.
{
{ DESIGN:
{
{ This interface is only callable by family administrators or above.
{
{   A validation record is put into the validation file and the record is
{ stored into the validation record information chain.  The record_id for this
{ validation record information entry is returned to the caller.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$create_account_member_rec
    (    account_name: avt$account_name;
         user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_account_name: avt$account_name,
      local_user_name: ost$user_name,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;
    record_id := osc$null_name;
    #CALLER_ID (caller_id);

  /create_account_member/
    BEGIN

{ Verify caller authority.

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$account_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /create_account_member/;
    IFEND;

{ Verify that a matching account exists for this account member.

    avp$verify_account_exists (account_name, account_exists, file_information, status);
    IF NOT status.normal THEN
      EXIT /create_account_member/;
    IFEND;
    IF NOT account_exists THEN
      osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
      EXIT /create_account_member/;
    IFEND;

{ Verify that reserved names are not being used.

    IF ((user_name = 'ALL') OR (user_name = 'NONE') OR (user_name = 'DEFAULT')) THEN
      osp$set_status_abnormal ('AV', ave$reserved_name_not_valid, user_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'account member', status);
      EXIT /create_account_member/;
    IFEND;

{ Create the account member record.

    key.account_name := account_name;
    key.project_name := osc$null_name;
    key.user_name := user_name;
    avp$create_data_record (key.value, avc$account_member_record_name, NIL, file_information, status);
    IF NOT status.normal THEN
      IF status.condition = ave$record_already_exists THEN
        osp$set_status_abnormal ('AV', ave$acct_member_already_exists, user_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
      IFEND;
      EXIT /create_account_member/;
    IFEND;

{ Read the account member record info and store it for later processing.

    local_account_name := account_name;
    local_user_name := user_name;
    read_account_member_record (caller_id, local_account_name, local_user_name, validation_record_info,
          file_information, status);
    IF NOT status.normal THEN
      EXIT /create_account_member/;
    IFEND;

    record_id := validation_record_info^.record_id;

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /create_account_member/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$account_member_record_name,
            validation_record_info^.work_area.sequence_pointer, file_information, status);
      IF NOT status.normal THEN
        EXIT /create_account_member/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CREATE_ACCOUNT_MEMBER_REC', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /create_account_member/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /create_account_member/;

    IF (NOT status.normal) AND (record_id <> osc$null_name) THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_create_record;
      description_record_name := avc$account_member_record_name;
      audit_information.create_validation_record.description_record_name_p := ^description_record_name;
      audit_information.create_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.create_validation_record.user_name_p := ^user_name;
      audit_information.create_validation_record.account_name_p := ^account_name;
      audit_information.create_validation_record.project_name_p := NIL;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$create_account_member_rec;
?? TITLE := '    avp$create_account_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to put an account record into the validation
{ file, and stores the record for subsequent changing of the field values
{ within the record.
{
{ DESIGN:
{
{ This interface is only callable by family administrators or above.
{
{   A validation record is put into the validation file and the record is
{ stored into the validation record information chain.  The record_id for this
{ validation record information entry is passed to the caller.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$create_account_record
    (    account_name: avt$account_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_account_name: avt$account_name,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      utility_information: ^avt$utility_information,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;
    record_id := osc$null_name;
    #CALLER_ID (caller_id);

  /create_account/
    BEGIN

{ Verify caller authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /create_account/;
    IFEND;

{ Verify that reserved names are not being used.

    IF ((account_name = 'ALL') OR (account_name = 'NONE') OR (account_name = 'DEFAULT') OR (account_name =
          'PUBLIC')) THEN
      osp$set_status_abnormal ('AV', ave$reserved_name_not_valid, account_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'account', status);
      EXIT /create_account/;
    IFEND;

{ Create the account record.

    key.account_name := account_name;
    key.project_name := osc$null_name;
    key.user_name := osc$null_name;
    avp$create_data_record (key.value, avc$account_record_name, NIL, file_information, status);
    IF NOT status.normal THEN
      IF status.condition = ave$record_already_exists THEN
        osp$set_status_abnormal ('AV', ave$account_already_exists, account_name, status);
      IFEND;
      EXIT /create_account/;
    IFEND;

{ Read the account record info and store it for later processing.

    local_account_name := account_name;
    read_account_record (caller_id, local_account_name, validation_record_info, file_information, status);
    IF NOT status.normal THEN
      EXIT /create_account/;
    IFEND;

    record_id := validation_record_info^.record_id;

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /create_account/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$account_record_name, validation_record_info^.work_area.sequence_pointer,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /create_account/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CREATE_ACCOUNT_RECORD', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /create_account/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /create_account/;

    IF (NOT status.normal) AND (record_id <> osc$null_name) THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_create_record;
      description_record_name := avc$account_record_name;
      audit_information.create_validation_record.description_record_name_p := ^description_record_name;
      audit_information.create_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.create_validation_record.user_name_p := NIL;
      audit_information.create_validation_record.account_name_p := ^account_name;
      audit_information.create_validation_record.project_name_p := NIL;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$create_account_record;
?? TITLE := '    avp$create_project_member_rec', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to put a project member record into the validation
{ file, and stores the record for subsequent changing of the field values
{ within the record.
{
{ DESIGN:
{
{ This interface is only callable by project administrators or above.
{
{   A validation record is put into the validation file and the record is
{ stored into the validation record information chain.  The record_id for this
{ validation record information entry is passed to the caller.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$create_project_member_rec
    (    account_name: avt$account_name;
         project_name: avt$project_name;
         user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_account_name: avt$account_name,
      local_project_name: avt$project_name,
      local_user_name: ost$user_name,
      project_exists: boolean,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;
    record_id := osc$null_name;
    #CALLER_ID (caller_id);

  /create_project_member/
    BEGIN

{ Verify caller authority.

    determine_caller_authority (caller_id, ^account_name, ^project_name, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$project_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /create_project_member/;
    IFEND;

{ Verify that a matching project exists for this project member.

    avp$verify_project_exists (account_name, project_name, project_exists, file_information, status);
    IF NOT status.normal THEN
      EXIT /create_project_member/;
    IFEND;
    IF NOT project_exists THEN
      osp$set_status_abnormal ('AV', ave$project_does_not_exist, project_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
      EXIT /create_project_member/;
    IFEND;

{ Verify that reserved names are not being used.

    IF ((user_name = 'ALL') OR (user_name = 'NONE') OR (user_name = 'DEFAULT')) THEN
      osp$set_status_abnormal ('AV', ave$reserved_name_not_valid, user_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'project member', status);
      EXIT /create_project_member/;
    IFEND;

{ Create the project member record.

    key.account_name := account_name;
    key.project_name := project_name;
    key.user_name := user_name;
    avp$create_data_record (key.value, avc$project_member_record_name, NIL, file_information, status);
    IF NOT status.normal THEN
      IF status.condition = ave$record_already_exists THEN
        osp$set_status_abnormal ('AV', ave$proj_member_already_exists, user_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, project_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
      IFEND;
      EXIT /create_project_member/;
    IFEND;

{ Read the project member record info and store it for later processing.

    local_account_name := account_name;
    local_project_name := project_name;
    local_user_name := user_name;
    read_project_member_record (caller_id, local_account_name, local_project_name, local_user_name,
          validation_record_info, file_information, status);
    IF NOT status.normal THEN
      EXIT /create_project_member/;
    IFEND;

    record_id := validation_record_info^.record_id;

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /create_project_member/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$project_member_record_name,
            validation_record_info^.work_area.sequence_pointer, file_information, status);
      IF NOT status.normal THEN
        EXIT /create_project_member/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CREATE_PROJECT_MEMBER_REC', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /create_project_member/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /create_project_member/;

    IF (NOT status.normal) AND (record_id <> osc$null_name) THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_create_record;
      description_record_name := avc$project_member_record_name;
      audit_information.create_validation_record.description_record_name_p := ^description_record_name;
      audit_information.create_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.create_validation_record.user_name_p := ^user_name;
      audit_information.create_validation_record.account_name_p := ^account_name;
      audit_information.create_validation_record.project_name_p := ^project_name;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$create_project_member_rec;
?? TITLE := '    avp$create_project_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to put a project record into the validation
{ file, and stores the record for subsequent changing of the field values
{ within the record.
{
{ DESIGN:
{
{ This interface is only callable by account administrators or above.
{
{   A validation record is put into the validation file and the record is
{ stored into the validation record information chain.  The record_id for this
{ validation record information entry is passed to the caller.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$create_project_record
    (    account_name: avt$account_name;
         project_name: avt$project_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ignore_status: ost$status,
      local_account_name: avt$account_name,
      local_project_name: avt$project_name,
      key: avt$validation_key,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;
    record_id := osc$null_name;
    #CALLER_ID (caller_id);

  /create_project/
    BEGIN

{ Verify caller authority.

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$account_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /create_project/;
    IFEND;

{ Verify that a matching account exists for this project.

    key.account_name := account_name;
    key.project_name := osc$null_name;
    key.user_name := osc$null_name;
    account_exists := FALSE;
    avp$determine_if_key_exists (key.value, account_exists, file_information, ignore_status);
    IF NOT account_exists THEN
      osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
      EXIT /create_project/;
    IFEND;

{ Verify that reserved names are not being used.

    IF ((project_name = 'ALL') OR (project_name = 'NONE') OR (project_name = 'DEFAULT') OR (project_name =
          'PUBLIC')) THEN
      osp$set_status_abnormal ('AV', ave$reserved_name_not_valid, project_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'project', status);
      EXIT /create_project/;
    IFEND;

{ Create the project record.

    key.project_name := project_name;
    avp$create_data_record (key.value, avc$project_record_name, NIL, file_information, status);
    IF NOT status.normal THEN
      IF status.condition = ave$record_already_exists THEN
        osp$set_status_abnormal ('AV', ave$project_already_exists, project_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
      IFEND;
      EXIT /create_project/;
    IFEND;

{ Read the project record info and store it for later processing.

    local_account_name := account_name;
    local_project_name := project_name;
    read_project_record (caller_id, local_account_name, local_project_name, validation_record_info,
          file_information, status);
    IF NOT status.normal THEN
      EXIT /create_project/;
    IFEND;

    record_id := validation_record_info^.record_id;

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /create_project/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$project_record_name, validation_record_info^.work_area.sequence_pointer,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /create_project/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CREATE_PROJECT_RECORD', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /create_project/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /create_project/;

    IF (NOT status.normal) AND (record_id <> osc$null_name) THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_create_record;
      description_record_name := avc$project_record_name;
      audit_information.create_validation_record.description_record_name_p := ^description_record_name;
      audit_information.create_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.create_validation_record.user_name_p := NIL;
      audit_information.create_validation_record.account_name_p := ^account_name;
      audit_information.create_validation_record.project_name_p := ^project_name;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$create_project_record;
?? TITLE := '    avp$create_user_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to put a user record into the validation
{ file, and stores the record for subsequent changing of the field values
{ within the record.
{
{ DESIGN:
{
{ This interface is only callable by user administrators or above.
{
{   A validation record is put into the validation file and the record is
{ stored into the validation record information chain.  The record_id for this
{ validation record information entry is passed to the caller.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$create_user_record
    (    user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      cycle_selection: pft$cycle_selector,
      cycle_no: fst$cycle_number,
      default_value: avt$field_value,
      descriptive_text: ^avt$descriptive_text,
      description_record_name: ost$name,
      evaluated_file_reference: fst$evaluated_file_reference,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      field_value_list_entry: ^avt$field_value_list_entry,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_status: ost$status,
      local_user_name: ost$user_name,
      path: ^pft$path,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      type_specification: avt$type_specification,
      string_value: ost$string,
      symptoms_out: fst$cycle_damage_symptoms,
      utility_information: ^avt$utility_information,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;
    record_id := osc$null_name;
    #CALLER_ID (caller_id);

  /create_user/
    BEGIN

{ Verify caller authority.

    executing_account_name := osc$null_name;
    executing_project_name := osc$null_name;
    pmp$get_account_project (executing_account_name, executing_project_name, ignore_status);
    determine_caller_authority (caller_id, NIL, NIL, NIL, ^executing_account_name, ^executing_project_name,
          caller_authority);
    IF caller_authority < avc$user_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /create_user/;
    IFEND;

{ Record the creation account and project if this is a user administrator.

    IF caller_authority < avc$family_admin_authority THEN
      PUSH field_value_list_entry;
      field_value_list_entry^.field_name := avc$creation_account_project;
      field_value_list_entry^.field_value.kind := avc$account_project_kind;
      field_value_list_entry^.field_value.account_name := ^executing_account_name;
      field_value_list_entry^.field_value.project_name := ^executing_project_name;
      field_value_list_entry^.forward := NIL;
    ELSE
      field_value_list_entry := NIL;
    IFEND;

{ Verify that reserved names are not being used.

    IF ((user_name = 'ALL') OR (user_name = 'NONE') OR (user_name = 'DEFAULT') OR (user_name = 'PUBLIC')) THEN
      osp$set_status_abnormal ('AV', ave$reserved_name_not_valid, user_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'user', status);
      EXIT /create_user/;
    IFEND;

{ Create the user record.

    key.account_name := avc$high_value_name;
    key.project_name := avc$high_value_name;
    key.user_name := user_name;
    avp$create_data_record (key.value, avc$user_record_name, field_value_list_entry, file_information,
          status);
    IF NOT status.normal THEN
      IF status.condition = ave$record_already_exists THEN
        osp$set_status_abnormal ('AV', ave$user_already_exists, user_name, status);
      IFEND;
      EXIT /create_user/;
    IFEND;

{ Read the user record info and store it for later processing.

    local_user_name := user_name;
    read_user_record (caller_id, local_user_name, validation_record_info, file_information, status);
    IF NOT status.normal THEN
      EXIT /create_user/;
    IFEND;

    record_id := validation_record_info^.record_id;

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /create_user/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$user_record_name, validation_record_info^.work_area.sequence_pointer,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /create_user/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CREATE_USER_RECORD', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /create_user/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

{ Get the default login password.

      avp$get_field_description (avc$login_password, validation_record_info^.description_record,
            {field_work_area=} NIL, type_specification, default_value, descriptive_text, utility_information,
            status);
      IF NOT status.normal THEN
        EXIT /create_user/;
      IFEND;

{ Change the login password to the default. (This will cause it to be encrypted)

      avp$change_login_password_value (avc$login_password, NIL, default_value.login_password, NIL, NIL, NIL,
            NIL, NIL, NIL, NIL, record_id, { update_batch_job_passwords = } FALSE, file_information, status);
      IF NOT status.normal THEN
        EXIT /create_user/;
      IFEND;

{ Set up the dual state link attribute user to default to the user.

      string_value.size := clp$trimmed_string_size (user_name);
      string_value.value := user_name;
      avp$change_string_value (avc$link_attribute_user, ^string_value, record_id, file_information, status);

    END /create_user/;

    IF NOT status.normal THEN
      IF record_id <> osc$null_name THEN
        avp$release_record_id (record_id, ignore_status);
        record_id := osc$null_name;
      IFEND;
    ELSE

{ Issue a warning if the master catalog already exists for this user.

      clp$evaluate_file_reference (file_information.file_name, $clt$file_ref_parsing_options[], TRUE,
            evaluated_file_reference, status);
      IF status.normal THEN
        IF (evaluated_file_reference.number_of_path_elements = 3) AND
          (fsp$path_element (^evaluated_file_reference, 2)^ = jmc$system_user) AND
          (fsp$path_element (^evaluated_file_reference, 3)^ = avc$validation_file_name) THEN

          PUSH path: [1 .. 3];
          path^ [1] := fsp$path_element (^evaluated_file_reference, 1)^;
          path^ [2] := user_name;
          pmp$get_unique_name (path^ [3], status);
          IF status.normal THEN
            cycle_selection.cycle_option := pfc$highest_cycle;
            pfp$utility_attach (path^ [3], path^, cycle_selection, osc$null_name, $pft$usage_selections [],
                  $pft$share_selections [], pfc$no_wait, $fst$cycle_damage_symptoms [], symptoms_out,
                  cycle_no, local_status);
            IF NOT local_status.normal THEN
              IF local_status.condition <> pfe$unknown_master_catalog THEN
                osp$set_status_abnormal ('AV', ave$master_catalog_exists, user_name, status);
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    IFEND;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_create_record;
      description_record_name := avc$user_record_name;
      audit_information.create_validation_record.description_record_name_p := ^description_record_name;
      audit_information.create_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.create_validation_record.user_name_p := ^user_name;
      audit_information.create_validation_record.account_name_p := NIL;
      audit_information.create_validation_record.project_name_p := NIL;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$create_user_record;
?? OLDTITLE ??
?? TITLE := '  Interfaces to read validation records' ??
?? NEWTITLE := '    avp$read_account_member_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read an account member record and store it
{ so that the field values within the record can be displayed by
{ authorized callers.
{
{ DESIGN:
{
{   This interface verifies that a matching account exists for the requested
{ account member and then calls a local procedure to read the account member
{ record into memory.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$read_account_member_record
    (VAR account_name: avt$account_name;
     VAR user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      caller_id: ost$caller_identifier,
      validation_record_info: ^avt$validation_record_info;

    #CALLER_ID (caller_id);

    status.normal := TRUE;

{ Verify a matching account record exists for the requested account member.

    avp$verify_account_exists (account_name, account_exists, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF account_exists THEN

{ Read the account member record and store it for later processing.

      read_account_member_record (caller_id, account_name, user_name, validation_record_info,
            file_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      record_id := validation_record_info^.record_id;
    ELSE
      osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
    IFEND;

  PROCEND avp$read_account_member_record;
?? TITLE := '    avp$read_account_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read an account record and store it so that
{ the field values within the record can be displayed by authorized callers.
{
{ DESIGN:
{
{   This interface calls a local procedure to read the account record into
{ memory.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$read_account_record
    (VAR account_name: avt$account_name;
     VAR record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      validation_record_info: ^avt$validation_record_info;

    #CALLER_ID (caller_id);

    status.normal := TRUE;

{ Read the account record and store it for later processing.

    read_account_record (caller_id, account_name, validation_record_info, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    record_id := validation_record_info^.record_id;

  PROCEND avp$read_account_record;
?? TITLE := '    avp$read_project_member_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read a project member record and store it so
{ that the field values within the record can be displayed by authorized callers.
{
{ DESIGN:
{
{   This interface verifies that a matching account and project exist for the
{ requested project member and then calls a local procedure to read the project
{ member record into memory.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$read_project_member_record
    (VAR account_name: avt$account_name;
     VAR project_name: avt$project_name;
     VAR user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      caller_id: ost$caller_identifier,
      project_exists: boolean,
      validation_record_info: ^avt$validation_record_info;

    #CALLER_ID (caller_id);

    status.normal := TRUE;

{ Verify a matching account record exists for the requested project member.

    avp$verify_account_exists (account_name, account_exists, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF account_exists THEN

{ Verify a matching project record exists for the requested project member.

      avp$verify_project_exists (account_name, project_name, project_exists, file_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF project_exists THEN

{ Read the project member record and store it for later processing.

        read_project_member_record (caller_id, account_name, project_name, user_name, validation_record_info,
              file_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        record_id := validation_record_info^.record_id;
      ELSE
        osp$set_status_abnormal ('AV', ave$project_does_not_exist, project_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
      IFEND;
    ELSE
      osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
    IFEND;

  PROCEND avp$read_project_member_record;
?? TITLE := '    avp$read_project_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read a project record and store it so that
{ the field values within the record can be displayed by authorized callers.
{
{ DESIGN:
{
{   This interface verifies that a matching account exists for the requested
{ project and then calls a local procedure to read the project
{ record into memory.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$read_project_record
    (VAR account_name: avt$account_name;
     VAR project_name: avt$project_name;
     VAR record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      caller_id: ost$caller_identifier,
      validation_record_info: ^avt$validation_record_info;

    #CALLER_ID (caller_id);

    status.normal := TRUE;

{ Verify a matching account record exists for the requested project.

    avp$verify_account_exists (account_name, account_exists, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    IF account_exists THEN

{ Read the project record and store it for later processing.

      read_project_record (caller_id, account_name, project_name, validation_record_info, file_information,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      record_id := validation_record_info^.record_id;
    ELSE
      osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
    IFEND;

  PROCEND avp$read_project_record;
?? TITLE := '    avp$read_user_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read a user record and store it so that
{ the field values within the record can be displayed by authorized callers.
{
{ DESIGN:
{
{   This interface calls a local procedure to read the user into
{ memory.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$read_user_record
    (VAR user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      validation_record_info: ^avt$validation_record_info;

    #CALLER_ID (caller_id);

    status.normal := TRUE;

{ Read the user record and store it for later processing.

    read_user_record (caller_id, user_name, validation_record_info, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    record_id := validation_record_info^.record_id;

  PROCEND avp$read_user_record;
?? OLDTITLE ??
?? TITLE := '  Interfaces to change validation records' ??
?? NEWTITLE := '    avp$change_account_member_rec', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read an account member record and store it so that
{ the field values within the record can be changed by authorized callers.
{
{ DESIGN:
{
{   This interface calls a local procedure to read the account member record into
{ memory.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$change_account_member_rec
    (    account_name: avt$account_name;
         user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_account_name: avt$account_name,
      local_user_name: ost$user_name,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Read the account member to be changed and store it for later processing.

    local_account_name := account_name;
    local_user_name := user_name;
    read_account_member_record (caller_id, local_account_name, local_user_name, validation_record_info,
          file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    record_id := validation_record_info^.record_id;

  /change_account_member/
    BEGIN

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /change_account_member/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$account_member_record_name,
            validation_record_info^.work_area.sequence_pointer, file_information, status);
      IF NOT status.normal THEN
        EXIT /change_account_member/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CHANGE_ACCOUNT_MEMBER_REC', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /change_account_member/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /change_account_member/;

    IF NOT status.normal THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

  PROCEND avp$change_account_member_rec;
?? TITLE := '    avp$change_account_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read an account record and store it so that
{ the field values within the record can be changed by authorized callers.
{
{ DESIGN:
{
{   This interface calls a local procedure to read the account record into
{ memory.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$change_account_record
    (    account_name: avt$account_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_account_name: avt$account_name,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Read the account to be changed and store it for later processing.

    local_account_name := account_name;
    read_account_record (caller_id, local_account_name, validation_record_info, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    record_id := validation_record_info^.record_id;

  /change_account/
    BEGIN

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /change_account/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$account_record_name, validation_record_info^.work_area.sequence_pointer,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /change_account/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CHANGE_ACCOUNT_RECORD', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /change_account/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /change_account/;

    IF NOT status.normal THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

  PROCEND avp$change_account_record;
?? TITLE := '    avp$change_project_member_rec', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read a project member record and store it so
{ that the field values within the record can be changed by authorized callers.
{
{ DESIGN:
{
{   This interface calls a local procedure to read the project member record into
{ memory.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$change_project_member_rec
    (    account_name: avt$account_name;
         project_name: avt$project_name;
         user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_account_name: avt$account_name,
      local_project_name: avt$project_name,
      local_user_name: ost$user_name,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Read the project member to be changed and store it for later processing.

    local_account_name := account_name;
    local_project_name := project_name;
    local_user_name := user_name;
    read_project_member_record (caller_id, local_account_name, local_project_name, local_user_name,
          validation_record_info, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    record_id := validation_record_info^.record_id;

  /change_project_member/
    BEGIN

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /change_project_member/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$project_member_record_name,
            validation_record_info^.work_area.sequence_pointer, file_information, status);
      IF NOT status.normal THEN
        EXIT /change_project_member/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CHANGE_PROJECT_MEMBER_REC', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /change_project_member/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /change_project_member/;

    IF NOT status.normal THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

  PROCEND avp$change_project_member_rec;
?? TITLE := '    avp$change_project_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read a project record and store it so that
{ the field values within the record can be changed by authorized callers.
{
{ DESIGN:
{
{   This interface calls a local procedure to read the project record into
{ memory.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$change_project_record
    (    account_name: avt$account_name;
         project_name: avt$project_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_account_name: avt$account_name,
      local_project_name: avt$project_name,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Read the project to be changed and store it for later processing.

    local_account_name := account_name;
    local_project_name := project_name;
    read_project_record (caller_id, local_account_name, local_project_name, validation_record_info,
          file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    record_id := validation_record_info^.record_id;

  /change_project/
    BEGIN

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /change_project/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$project_record_name, validation_record_info^.work_area.sequence_pointer,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /change_project/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CHANGE_PROJECT_RECORD', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /change_project/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /change_project/;

    IF NOT status.normal THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

  PROCEND avp$change_project_record;
?? TITLE := '    avp$change_user_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to read a user record and store it so that
{ the field values within the record can be changed by authorized callers.
{
{ DESIGN:
{
{   A less privileged user can not change the values of a more privileged user.
{
{   This interface calls a local procedure to read the user record into
{ memory.
{
{   The number of command entries in the record utility information for this
{ record is returned to the caller.
{
{   The assigned record id is returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$change_user_record
    (VAR user_name: ost$user_name;
     VAR record_id: ost$name;
     VAR number_of_command_entries: integer;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      descriptive_text: ^avt$descriptive_text,
      family_admin_value: avt$field_value,
      field_value: avt$field_value,
      ignore_status: ost$status,
      key: avt$validation_key,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_size: integer,
      system_admin_value: avt$field_value,
      type_specification: avt$type_specification,
      user_identification: ost$user_identification,
      utility_information: ^avt$utility_information,
      validation_record_info: ^avt$validation_record_info;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Read the user to be changed and store it for later processing.

    read_user_record (caller_id, user_name, validation_record_info, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    record_id := validation_record_info^.record_id;

  /change_user/
    BEGIN

{ Determine if a system administrator is being changed.

      avp$get_field (avc$system_administration, validation_record_info^.data_record,
            validation_record_info^.description_record, validation_record_info^.work_area.sequence_pointer,
            system_admin_value, type_specification, default_value, descriptive_text, utility_information,
            status);
      IF NOT status.normal THEN
        EXIT /change_user/;
      IFEND;

{ Determine if a family administrator is being changed.

      avp$get_field (avc$family_administration, validation_record_info^.data_record,
            validation_record_info^.description_record, validation_record_info^.work_area.sequence_pointer,
            family_admin_value, type_specification, default_value, descriptive_text, utility_information,
            status);
      IF NOT status.normal THEN
        EXIT /change_user/;
      IFEND;

{ Verify that a less privileged user is not changing a more privileged user.

      IF ((system_admin_value.capability^) AND (validation_record_info^.caller_authority <
            avc$system_admin_authority)) OR ((family_admin_value.capability^) AND
            (validation_record_info^.caller_authority < avc$family_admin_authority)) THEN
        pmp$get_user_identification (user_identification, ignore_status);
        IF user_identification.user <> user_name THEN
          osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          EXIT /change_user/;
        IFEND;
      IFEND;

{ Create a scratch segment to hold the field value changes.

      mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, validation_record_info^.work_area,
            status);
      IF NOT status.normal THEN
        EXIT /change_user/;
      IFEND;
      RESET validation_record_info^.work_area.sequence_pointer;

{ Retrieve the record utility information so that the number of
{ subcommand entries may be returned.

      avp$get_desc_utility_info (avc$user_record_name, validation_record_info^.work_area.sequence_pointer,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /change_user/;
      IFEND;

      record_utility_info_size := i#current_sequence_position
            (validation_record_info^.work_area.sequence_pointer);
      RESET validation_record_info^.work_area.sequence_pointer;

      NEXT validation_record_info^.record_utility_information: [[REP record_utility_info_size OF cell]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET validation_record_info^.record_utility_information;
      NEXT record_utility_info_header IN validation_record_info^.record_utility_information;
      IF record_utility_info_header = NIL THEN
        corrupted_sequence ('AVP$CHANGE_USER_RECORD', 'RECORD_UTILITY_INFO_HEADER',
              'RECORD_UTILITY_INFORMATION', status);
        EXIT /change_user/;
      IFEND;
      number_of_command_entries := record_utility_info_header^.number_of_entries;

    END /change_user/;

    IF NOT status.normal THEN
      avp$release_record_id (record_id, ignore_status);
      record_id := osc$null_name;
    IFEND;

  PROCEND avp$change_user_record;
?? OLDTITLE ??
?? TITLE := '  Interfaces to delete validation records' ??
?? NEWTITLE := '    avp$delete_account_member_rec', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to delete a specified account member record, or all
{ account members of a specified account, from a validation file .
{
{ DESIGN:
{
{   This interface is only callable by account administrators or above.
{

  PROCEDURE [XDCL, #GATE] avp$delete_account_member_rec
    (    account_name: avt$account_name;
         user_name: ost$user_name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_administrator: boolean,
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ending_key: avt$validation_key,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      ignore_status: ost$status,
      key: avt$validation_key,
      required_authority: avt$validation_authority,
      starting_key: avt$validation_key,
      type_specification: avt$type_specification,
      utility_information: ^avt$utility_information;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

  /delete_account_member/
    BEGIN

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$account_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /delete_account_member/;
    IFEND;

{ Delete all members from the specified account if requested.

    IF user_name = 'ALL' THEN
      starting_key.account_name := account_name;
      starting_key.project_name := osc$null_name;
      starting_key.user_name := osc$null_name;
      ending_key.account_name := account_name;
      ending_key.project_name := osc$null_name;
      ending_key.user_name := avc$high_value_name;
      avp$delete_data_records (starting_key.value, ending_key.value, avc$account_member_record_name,
            file_information, status);
    ELSE

{ Delete the specified account member.

      key.account_name := account_name;
      key.project_name := osc$null_name;
      key.user_name := user_name;
      avp$delete_data_record (key.value, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          osp$set_status_abnormal ('AV', ave$acct_member_does_not_exist, user_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
        IFEND;
      IFEND;
    IFEND;
    END /delete_account_member/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_delete_record;
      description_record_name := avc$account_member_record_name;
      audit_information.delete_validation_record.description_record_name_p := ^description_record_name;
      audit_information.delete_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.delete_validation_record.user_name_p := ^user_name;
      audit_information.delete_validation_record.account_name_p := ^account_name;
      audit_information.delete_validation_record.project_name_p := NIL;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$delete_account_member_rec;
?? TITLE := '    avp$delete_account_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to delete a specified account record, or all account
{ records, from a validation file.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   A specified account or all accounts may be deleted.
{
{   When any account is deleted all projects within the account (and
{ project members of those projects) are deleted, as well as all
{ account members of the account.
{

  PROCEDURE [XDCL, #GATE] avp$delete_account_record
    (    account_name: avt$account_name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      ending_key: avt$validation_key,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ignore_status: ost$status,
      key: avt$validation_key,
      starting_key: avt$validation_key;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

  /delete_account/
    BEGIN

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /delete_account/;
    IFEND;

{ Delete all account information if specified.

    IF account_name = 'ALL' THEN
      starting_key.account_name := osc$null_name;
      starting_key.project_name := osc$null_name;
      starting_key.user_name := osc$null_name;
      ending_key.account_name := avc$high_value_name;
      ending_key.project_name := osc$null_name;
      ending_key.user_name := osc$null_name;

{ Delete all project members.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_member_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_account/;
      IFEND;

{ Delete all projects.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_account/;
      IFEND;

{ Delete all account members.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$account_member_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_account/;
      IFEND;

{ Delete all accounts.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$account_record_name,
            file_information, status);
    ELSE

{ Delete the specified accounts information.

      starting_key.account_name := account_name;
      starting_key.project_name := osc$null_name;
      starting_key.user_name := osc$null_name;
      ending_key.account_name := account_name;
      ending_key.project_name := avc$high_value_name;
      ending_key.user_name := avc$high_value_name;

{ Delete the project members within the specified account.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_member_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_account/;
      IFEND;

{ Delete the projects within the specified account.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_account/;
      IFEND;

{ Delete the account members within the specified account.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$account_member_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_account/;
      IFEND;

{ Delete the specified account.

      key.account_name := account_name;
      key.project_name := osc$null_name;
      key.user_name := osc$null_name;

      avp$delete_data_record (key.value, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
        IFEND;
      IFEND;
    IFEND;
    END /delete_account/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_delete_record;
      description_record_name := avc$account_record_name;
      audit_information.delete_validation_record.description_record_name_p := ^description_record_name;
      audit_information.delete_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.delete_validation_record.user_name_p := NIL;
      audit_information.delete_validation_record.account_name_p := ^account_name;
      audit_information.delete_validation_record.project_name_p := NIL;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$delete_account_record;
?? TITLE := '    avp$delete_project_member_rec', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to delete a specified project member record from a
{ validation file, or all project members of a specified account.
{
{ DESIGN:
{
{   This interface is only callable by project administrators or above.
{

  PROCEDURE [XDCL, #GATE] avp$delete_project_member_rec
    (    account_name: avt$account_name;
         project_name: avt$project_name;
         user_name: ost$user_name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_administrator: boolean,
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ending_key: avt$validation_key,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      ignore_status: ost$status,
      key: avt$validation_key,
      required_authority: avt$validation_authority,
      starting_key: avt$validation_key,
      type_specification: avt$type_specification,
      utility_information: ^avt$utility_information;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

  /delete_project_member/
    BEGIN

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, ^account_name, ^project_name, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$project_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /delete_project_member/;
    IFEND;

{ Delete all project member information for the specified account if specified.

    IF user_name = 'ALL' THEN
      starting_key.account_name := account_name;
      starting_key.project_name := project_name;
      starting_key.user_name := osc$null_name;
      ending_key.account_name := account_name;
      ending_key.project_name := project_name;
      ending_key.user_name := avc$high_value_name;

{ Delete all project members for the specified account.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_member_record_name,
            file_information, status);
    ELSE

{ Delete the specified project member.

      key.account_name := account_name;
      key.project_name := project_name;
      key.user_name := user_name;
      avp$delete_data_record (key.value, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          osp$set_status_abnormal ('AV', ave$proj_member_does_not_exist, user_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, project_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
        IFEND;
      IFEND;
    IFEND;
    END /delete_project_member/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_delete_record;
      description_record_name := avc$project_member_record_name;
      audit_information.delete_validation_record.description_record_name_p := ^description_record_name;
      audit_information.delete_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.delete_validation_record.user_name_p := ^user_name;
      audit_information.delete_validation_record.account_name_p := ^account_name;
      audit_information.delete_validation_record.project_name_p := ^project_name;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$delete_project_member_rec;
?? TITLE := '    avp$delete_project_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to delete a specified project record, or all project
{ records of a specified account, from a validation file.
{
{ DESIGN:
{
{   This interface is only callable by account administrators or above.
{

  PROCEDURE [XDCL, #GATE] avp$delete_project_record
    (    account_name: avt$account_name;
         project_name: avt$project_name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_administrator: boolean,
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      description_record_name: ost$name,
      ending_key: avt$validation_key,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      key: avt$validation_key,
      ignore_status: ost$status,
      starting_key: avt$validation_key;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

  /delete_project/
    BEGIN

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$account_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /delete_project/;
    IFEND;

{ Delete all project information for the specified account if specified.

    IF project_name = 'ALL' THEN
      starting_key.account_name := account_name;
      starting_key.project_name := osc$null_name;
      starting_key.user_name := osc$null_name;
      ending_key.account_name := account_name;
      ending_key.project_name := avc$high_value_name;
      ending_key.user_name := avc$high_value_name;

{ Delete project member records for the specified account.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_member_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_project/;
      IFEND;

{ Delete project records for the specified account.

      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_record_name,
            file_information, status);
    ELSE

{ delete all project members for the specified project.

      starting_key.account_name := account_name;
      starting_key.project_name := project_name;
      starting_key.user_name := osc$null_name;
      ending_key.account_name := account_name;
      ending_key.project_name := project_name;
      ending_key.user_name := avc$high_value_name;
      avp$delete_data_records (starting_key.value, ending_key.value, avc$project_member_record_name,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /delete_project/;
      IFEND;

{ Delete the specified project.

      key.account_name := account_name;
      key.project_name := project_name;
      key.user_name := osc$null_name;
      avp$delete_data_record (key.value, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          osp$set_status_abnormal ('AV', ave$project_does_not_exist, project_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
        IFEND;
      IFEND;
    IFEND;
    END /delete_project/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_delete_record;
      description_record_name := avc$project_record_name;
      audit_information.delete_validation_record.description_record_name_p := ^description_record_name;
      audit_information.delete_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.delete_validation_record.user_name_p := NIL;
      audit_information.delete_validation_record.account_name_p := ^account_name;
      audit_information.delete_validation_record.project_name_p := ^project_name;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$delete_project_record;
?? TITLE := '    avp$delete_user_record', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to delete a specified user record from a validation file.
{
{ DESIGN:
{
{   This interface is only callable by user administrators or above.
{
{   Deletion of the current executing user is not allowed.
{
{   A less privileged user can not delete a more privileged user.
{

  PROCEDURE [XDCL, #GATE] avp$delete_user_record
    (    user_name: ost$user_name;
         delete_files: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      description_record_name: ost$name,
      descriptive_text: ^avt$descriptive_text,
      evaluated_file_reference: fst$evaluated_file_reference,
      executing_id: ost$user_identification,
      family_admin_value: avt$field_value,
      field_value: avt$field_value,
      ignore_status: ost$status,
      key: avt$validation_key,
      local_user_name: ost$user_name,
      number_of_command_entries: integer,
      path: ^pft$path,
      record_id: ost$name,
      set_name: stt$set_name,
      system_admin_value: avt$field_value,
      type_specification: avt$type_specification,
      user_path: ^pft$path,
      utility_information: ^avt$utility_information,
      validation_record_info: ^avt$validation_record_info;

?? NEWTITLE := '      block_exit_handler', EJECT ??
{
{ PURPOSE:
{
{   This block exit condition handler ensures that the family administration
{   flag used by permanent files is reset to the appropriate value if it has
{   been temporarily changed to allow a user administrator to delete the master
{   catalog for a user under the control of the user administrator.
{

    PROCEDURE block_exit_handler
      (    condition: pmt$condition;
           condition_information: ^pmt$condition_information;
           save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      handler_status.normal := TRUE;

      pfp$set_family_administrator (FALSE);

    PROCEND block_exit_handler;
?? OLDTITLE, EJECT ??
    status.normal := TRUE;

    #CALLER_ID (caller_id);

  /delete_user/
    BEGIN

{ Verify that the current executing user is not being deleted.

    pmp$get_user_identification (executing_id, status);
    IF NOT status.normal THEN
      EXIT /delete_user/;
    IFEND;
    IF executing_id.user = user_name THEN
      osp$set_status_abnormal ('AV', ave$can_not_delete_current, 'USER', status);
      EXIT /delete_user/;
    IFEND;

    key.account_name := avc$high_value_name;
    key.project_name := avc$high_value_name;
    key.user_name := user_name;

{ Read the user being deleted to determine his administration privileges.
{ NOTE: This call will validate that the caller has user administration authority or above.

    local_user_name := user_name;
    read_user_record (caller_id, local_user_name, validation_record_info, file_information, status);
    IF NOT status.normal THEN
      EXIT /delete_user/;
    IFEND;

    record_id := validation_record_info^.record_id;

  /validation_record_read/
    BEGIN

{ Determine if the user being deleted is a system administrator.

      avp$get_field (avc$system_administration, validation_record_info^.data_record,
            validation_record_info^.description_record, validation_record_info^.work_area.sequence_pointer,
            system_admin_value, type_specification, default_value, descriptive_text, utility_information,
            status);
      IF NOT status.normal THEN
        EXIT /validation_record_read/;
      IFEND;

{ Determine if the user being deleted is a family administrator.

      avp$get_field (avc$family_administration, validation_record_info^.data_record,
            validation_record_info^.description_record, validation_record_info^.work_area.sequence_pointer,
            family_admin_value, type_specification, default_value, descriptive_text, utility_information,
            status);
      IF NOT status.normal THEN
        EXIT /validation_record_read/;
      IFEND;

{ Verify that a less privileged user is not deleting a more privileged user.

      IF ((system_admin_value.capability^) AND (validation_record_info^.caller_authority <
            avc$system_admin_authority)) OR ((family_admin_value.capability^) AND
            (validation_record_info^.caller_authority < avc$family_admin_authority)) THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /validation_record_read/;
      IFEND;

{ Delete all of the users files if requested.

      IF delete_files THEN

{ Determine if this is a system validation file.  If not, return an error.

        clp$evaluate_file_reference (file_information.file_name, $clt$file_ref_parsing_options[], TRUE,
              evaluated_file_reference, status);
        IF NOT status.normal THEN
          EXIT /validation_record_read/;
        IFEND;

        IF NOT ((evaluated_file_reference.number_of_path_elements = 3) AND
              (fsp$path_element (^evaluated_file_reference, 2)^ = jmc$system_user) AND
              (fsp$path_element (^evaluated_file_reference, 3)^ = avc$validation_file_name)) THEN
          osp$set_status_abnormal ('AV', ave$delete_files_not_allowed, '', status);
          EXIT /validation_record_read/;
        IFEND;

        PUSH user_path: [1 .. 2];
        user_path^ [1] := fsp$path_element (^evaluated_file_reference, 1)^;
        user_path^ [2] := user_name;

{ If the user doing the delete is a user administrator, temporarily make the user
{ look like a family administrator so that the permanent files may be deleted.

        IF validation_record_info^.caller_authority = avc$user_admin_authority THEN
          osp$establish_block_exit_hndlr (^block_exit_handler);
          pfp$set_family_administrator (TRUE);
        IFEND;

        pfp$purge_catalog_contents (user_path^, FALSE, status);
        IF NOT status.normal THEN
          IF status.condition = pfe$unknown_master_catalog THEN
            status.normal := TRUE;
          ELSE
            EXIT /validation_record_read/;
          IFEND;
        IFEND;

        osp$get_set_name (user_path^ [1], set_name, status);
        IF NOT status.normal THEN
          EXIT /validation_record_read/;
        IFEND;
        pfp$purge_master_catalog (set_name, user_path^ [1], user_name, status);
        IF NOT status.normal THEN
          IF status.condition = pfe$unknown_master_catalog THEN
            status.normal := TRUE;
          ELSE
            EXIT /validation_record_read/;
          IFEND;
        IFEND;

        IF validation_record_info^.caller_authority = avc$user_admin_authority THEN
          pfp$set_family_administrator (FALSE);
          osp$disestablish_cond_handler;
        IFEND;
      IFEND;

{ Delete the user record.

      avp$delete_data_record (key.value, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          osp$set_status_abnormal ('AV', ave$user_does_not_exist, user_name, status);
        IFEND;
        EXIT /validation_record_read/;
      IFEND;

    END /validation_record_read/;

    IF status.normal THEN
      avp$release_record_id (record_id, status);
    ELSE
      avp$release_record_id (record_id, ignore_status);
    IFEND;
    END /delete_user/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_delete_record;
      description_record_name := avc$user_record_name;
      audit_information.delete_validation_record.description_record_name_p := ^description_record_name;
      audit_information.delete_validation_record.validation_file_p := ^file_information.file_name;
      audit_information.delete_validation_record.user_name_p := ^user_name;
      audit_information.delete_validation_record.account_name_p := NIL;
      audit_information.delete_validation_record.project_name_p := NIL;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$delete_user_record;
?? OLDTITLE ??
?? TITLE := '  Interfaces to verify validation records exist' ??
?? NEWTITLE := '    avp$verify_acct_member_exists', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to determine whether or not a specified account
{ member record exists on a validation file.
{
{ DESIGN:
{
{   This interface is only callable by account administrators or above.
{

  PROCEDURE [XDCL, #GATE] avp$verify_acct_member_exists
    (    account_name: avt$account_name;
         user_name: ost$user_name;
     VAR account_member_exists: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      account_administrator: boolean,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      ignore_status: ost$status,
      key: avt$validation_key;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$account_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Determine if a record for the specified account member exists on the
{ validation file.

    key.account_name := account_name;
    key.project_name := osc$null_name;
    key.user_name := user_name;
    avp$determine_if_key_exists (key.value, account_member_exists, file_information, status);
    IF NOT account_member_exists THEN

{ Reset the status if the account does not exist.

      account_exists := FALSE;
      avp$verify_account_exists (account_name, account_exists, file_information, ignore_status);
      IF NOT account_exists THEN
        osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
      IFEND;
    IFEND;

  PROCEND avp$verify_acct_member_exists;
?? TITLE := '    avp$verify_account_exists', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to determine whether or not a specified account
{ record exists on a validation file.
{
{ DESIGN:
{
{   This interface is not protected.
{

  PROCEDURE [XDCL, #GATE] avp$verify_account_exists
    (    account_name: avt$account_name;
     VAR account_exists: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      key: avt$validation_key;

    status.normal := TRUE;

{ Determine if a record for the specified account exists on the
{ validation file.

    key.account_name := account_name;
    key.project_name := osc$null_name;
    key.user_name := osc$null_name;
    avp$determine_if_key_exists (key.value, account_exists, file_information, status);

  PROCEND avp$verify_account_exists;
?? TITLE := '    avp$verify_project_exists', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to determine whether or not a specified project
{ record exists on a validation file.
{
{ DESIGN:
{
{   This interface is not protected.
{

  PROCEDURE [XDCL, #GATE] avp$verify_project_exists
    (    account_name: avt$account_name;
         project_name: avt$project_name;
     VAR project_exists: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      ignore_status: ost$status,
      key: avt$validation_key;

    status.normal := TRUE;

{ Determine if a record for the specified project exists on the
{ validation file.

    key.account_name := account_name;
    key.project_name := project_name;
    key.user_name := osc$null_name;
    avp$determine_if_key_exists (key.value, project_exists, file_information, status);
    IF NOT project_exists THEN

{ Reset the status if the account does not exist.

      account_exists := FALSE;
      avp$verify_account_exists (account_name, account_exists, file_information, ignore_status);
      IF NOT account_exists THEN
        osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
      IFEND;
    IFEND;

  PROCEND avp$verify_project_exists;
?? TITLE := '    avp$verify_proj_member_exists', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to determine whether or not a specified project
{ member record exists on a validation file.
{
{ DESIGN:
{
{   This interface is only callable by project administrators or above.
{

  PROCEDURE [XDCL, #GATE] avp$verify_proj_member_exists
    (    account_name: avt$account_name;
         project_name: avt$project_name;
         user_name: ost$user_name;
     VAR project_member_exists: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      account_administrator: boolean,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      project_administrator: boolean,
      project_exists: boolean,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      ignore_status: ost$status,
      key: avt$validation_key;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$project_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Determine if a record for the specified project member exists on the
{ validation file.

    key.account_name := account_name;
    key.project_name := project_name;
    key.user_name := user_name;
    avp$determine_if_key_exists (key.value, project_member_exists, file_information, status);
    IF NOT project_member_exists THEN

      { Reset the status if the project does not exist.

      project_exists := FALSE;
      avp$verify_project_exists (account_name, project_name, project_exists, file_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF NOT project_exists THEN
        osp$set_status_abnormal ('AV', ave$project_does_not_exist, project_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
      IFEND;

    IFEND;

  PROCEND avp$verify_proj_member_exists;
?? TITLE := '    avp$verify_user_exists', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to determine whether or not a specified user
{ record exists on a validation file.
{
{ DESIGN:
{
{   This interface is only callable by user administrators or above.
{

  PROCEDURE [XDCL, #GATE] avp$verify_user_exists
    (    user_name: ost$user_name;
     VAR user_exists: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_administrator: boolean,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      creation_account_name: avt$account_name,
      creation_project_name: avt$project_name,
      data_record: ^avt$template_file_record,
      data_record_size: 0 .. avc$max_template_record_size,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      description_record_name: ost$name,
      description_record_size: 0 .. avc$max_template_record_size,
      descriptive_text: ^avt$descriptive_text,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      executing_user_name: ost$user_identification,
      field_count: avt$field_count,
      field_value: avt$field_value,
      ignore_status: ost$status,
      key: avt$validation_key,
      type_specification: avt$type_specification,
      utility_information: ^avt$utility_information;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$user_authority THEN

{ Determine if caller has user administration authority for this user.

      key.account_name := avc$high_value_name;
      key.project_name := avc$high_value_name;
      key.user_name := user_name;
      PUSH data_record: [[REP avc$max_template_record_size OF cell]];
      RESET data_record;
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;

{ Read the user record to get the creation account and project.

      avp$read_data_record (key.value, avc$read_access, TRUE, data_record, data_record_size,
            description_record, description_record_size, description_record_name, field_count,
            file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        IFEND;
        RETURN;
      IFEND;
      avp$get_field (avc$creation_account_project, data_record, description_record, {work_area=} NIL,
            field_value, type_specification, default_value, descriptive_text, utility_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      creation_account_name := field_value.account_name^;
      creation_project_name := field_value.project_name^;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, ^creation_account_name, ^creation_project_name,
            caller_authority);
      IF caller_authority < avc$user_admin_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        RETURN;
      IFEND;
    IFEND;

{ Determine if a record for the specified user exists on the
{ validation file.

    key.account_name := avc$high_value_name;
    key.project_name := avc$high_value_name;
    key.user_name := user_name;
    avp$determine_if_key_exists (key.value, user_exists, file_information, status);

  PROCEND avp$verify_user_exists;
?? OLDTITLE ??
?? TITLE := '  Interfaces to create field descriptions' ??
?? NEWTITLE := '    avp$create_acct_proj_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new account project type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters.
{
{   Then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{
{   A warning status is returned if the account and/or project do not exist in
{ the validation file and the system validation level is currently account or
{ project.
{

  PROCEDURE [XDCL, #GATE] avp$create_acct_proj_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         account_name: avt$account_name;
         project_name: avt$project_name;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      key: avt$validation_key,
      ignore_status: ost$status,
      project_exists: boolean,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$account_project_kind;
    default_value.account_name := ^account_name;
    default_value.project_name := ^project_name;

{ Initialize the type specification values.

    type_specification.kind := avc$account_project_kind;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority,
          avc$change_acct_proj_command, default_value, type_specification, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND avp$create_acct_proj_field;
?? TITLE := '    avp$create_accum_limit_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new accumulating limit type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_accum_limit_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         job_warning_limit: avt$limit_value;
         job_maximum_limit: avt$limit_value;
         total_limit: avt$limit_value;
         limit_name: ost$name;
         job_limits_apply: boolean;
         limit_update_statistics: ^sft$limit_update_statistics;
         minimum_job_limit_value: avt$limit_value;
         maximum_job_limit_value: avt$limit_value;
         total_limit_applies: boolean;
         total_limit_stops_login: boolean;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification,
      zero_value: integer;

    status.normal := TRUE;
    zero_value := 0;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$accumulating_limit_kind;
    default_value.job_warning_limit := ^job_warning_limit;
    default_value.job_maximum_limit := ^job_maximum_limit;
    default_value.total_limit := ^total_limit;
    default_value.total_accumulation := ^zero_value;

{ Initialize the type specification values.

    type_specification.kind := avc$accumulating_limit_kind;
    type_specification.limit_name := ^limit_name;
    type_specification.job_limits_apply := ^job_limits_apply;
    type_specification.limit_update_statistics := limit_update_statistics;
    type_specification.minimum_job_limit_value := ^minimum_job_limit_value;
    type_specification.maximum_job_limit_value := ^maximum_job_limit_value;
    type_specification.total_limit_applies := ^total_limit_applies;
    type_specification.total_limit_stops_login := ^total_limit_stops_login;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority,
          avc$change_accum_limit_command, default_value, type_specification, file_information, status);

  PROCEND avp$create_accum_limit_field;
?? TITLE := '    avp$create_capability_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new capability type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_capability_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         capability: boolean;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$capability_kind;
    default_value.capability := ^capability;

{ Initialize the type specification values.

    type_specification.kind := avc$capability_kind;

{ Create the field.

    create_field (field_name, validation_record_name, NIL, NIL, description, display_authority,
          change_authority, manage_authority, delete_authority, osc$null_name, default_value,
          type_specification, file_information, status);

  PROCEND avp$create_capability_field;
?? TITLE := '    avp$create_date_time_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new date time type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_date_time_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         date_time: avt$date_time;
         date_time_range: boolean;
         date_applies: boolean;
         time_applies: boolean;
         date_display_format: clt$date_time_form_string;
         time_display_format: clt$date_time_form_string;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$date_time_kind;
    default_value.date_time := ^date_time;

{ Initialize the type specification values.

    type_specification.kind := avc$date_time_kind;
    type_specification.date_time_range := ^date_time_range;
    type_specification.date_applies := ^date_applies;
    type_specification.time_applies := ^time_applies;
    type_specification.date_display_format := ^date_display_format;
    type_specification.time_display_format := ^time_display_format;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority,
          avc$change_date_time_command, default_value, type_specification, file_information, status);

  PROCEND avp$create_date_time_field;
?? TITLE := '    avp$create_file_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new file type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_file_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         file: fst$file_reference;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$file_kind;
    default_value.file := ^file;

{ Initialize the type specification values.

    type_specification.kind := avc$file_kind;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority, avc$change_file_command,
          default_value, type_specification, file_information, status);

  PROCEND avp$create_file_field;
?? TITLE := '    avp$create_integer_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new integer type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_integer_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         integer_value: integer;
         minimum_integer_value: integer;
         maximum_integer_value: integer;
         integer_display_format: avt$numeric_display_format;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$integer_kind;
    default_value.integer_value := ^integer_value;

{ Initialize the type specification values.

    type_specification.kind := avc$integer_kind;
    type_specification.minimum_integer_value := ^minimum_integer_value;
    type_specification.maximum_integer_value := ^maximum_integer_value;
    type_specification.integer_display_format := ^integer_display_format;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority, avc$change_integer_command,
          default_value, type_specification, file_information, status);

  PROCEND avp$create_integer_field;
?? TITLE := '    avp$create_job_class_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new job class type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_job_class_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         job_classes: avt$name_list;
         batch_job_class_default: ost$name;
         interactive_job_class_default: ost$name;
         common_job_classes: avt$name_list;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$job_class_kind;
    default_value.job_classes := ^job_classes;
    default_value.batch_job_class_default := ^batch_job_class_default;
    default_value.interactive_job_class_default := ^interactive_job_class_default;

{ Initialize the type specification values.

    type_specification.kind := avc$job_class_kind;
    type_specification.common_job_classes := ^common_job_classes;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority,
          avc$change_job_class_command, default_value, type_specification, file_information, status);

  PROCEND avp$create_job_class_field;
?? TITLE := '    avp$create_labeled_names_field', EJECT ??
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new labeled names type validation field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_labeled_names_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         labeled_names: avt$labeled_names_list;
         valid_labels: avt$name_list;
         valid_names: avt$name_list;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      index: avt$name_list_size,
      labeled_names_default: ^array [1 .. *] of avt$labeled_names,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    PUSH labeled_names_default: [1 .. UPPERBOUND (labeled_names)];
    FOR index := 1 to UPPERBOUND (labeled_names) DO
      PUSH labeled_names_default^ [index].label;
      labeled_names_default^ [index].label^ := labeled_names [index].label^;
      PUSH labeled_names_default^ [index].names: [1 .. UPPERBOUND (labeled_names [index].names^)];
      labeled_names_default^ [index].names^ := labeled_names [index].names^;
    FOREND;

    default_value.kind := avc$labeled_names_kind;
    default_value.labeled_names := labeled_names_default;

{ Initialize the type specification values.

    type_specification.kind := avc$labeled_names_kind;
    type_specification.valid_labels := ^valid_labels;
    type_specification.valid_names := ^valid_names;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority,
          avc$change_labeled_names_cmd, default_value, type_specification, file_information, status);

  PROCEND avp$create_labeled_names_field;
?? TITLE := '    avp$create_limit_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new limit type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_limit_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         limit_value: avt$limit_value;
         minimum_limit_value: avt$limit_value;
         maximum_limit_value: avt$limit_value;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$limit_kind;
    default_value.limit_value := ^limit_value;

{ Initialize the type specification values.

    type_specification.kind := avc$limit_kind;
    type_specification.minimum_limit_value := ^minimum_limit_value;
    type_specification.maximum_limit_value := ^maximum_limit_value;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority, avc$change_limit_command,
          default_value, type_specification, file_information, status);

  PROCEND avp$create_limit_field;
?? TITLE := '    avp$create_login_password_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new login password type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_login_password_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         login_password: avt$login_password;
         login_password_exp_date: ost$date_time;
         login_password_exp_interval: pmt$time_increment;
         login_password_max_exp_interval: pmt$time_increment;
         login_password_exp_warning: pmt$time_increment;
         login_password_exp_chg_interval: pmt$time_increment;
         login_password_attributes: avt$name_list;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$login_password_kind;
    default_value.login_password := ^login_password;
    default_value.login_password_exp_date := ^login_password_exp_date;
    default_value.login_password_exp_interval := ^login_password_exp_interval;
    default_value.login_password_max_exp_interval := ^login_password_max_exp_interval;
    default_value.login_password_exp_warning := ^login_password_exp_warning;
    default_value.login_password_exp_chg_interval := ^login_password_exp_chg_interval;
    default_value.login_password_change_date := NIL;
    default_value.login_password_attributes := ^login_password_attributes;

{ Initialize the type specification values.

    type_specification.kind := avc$login_password_kind;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority,
          avc$change_login_password_cmd, default_value, type_specification, file_information, status);

  PROCEND avp$create_login_password_field;
?? TITLE := '    avp$create_name_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new name type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_name_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         names: avt$name_list;
         minimum_number_of_names: avt$name_list_size;
         maximum_number_of_names: avt$name_list_size;
         common_names: avt$name_list;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$name_kind;
    default_value.names := ^names;

{ Initialize the type specification values.

    type_specification.kind := avc$name_kind;
    type_specification.minimum_number_of_names := ^minimum_number_of_names;
    type_specification.maximum_number_of_names := ^maximum_number_of_names;
    type_specification.common_names := ^common_names;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority, avc$change_name_command,
          default_value, type_specification, file_information, status);

  PROCEND avp$create_name_field;
?? TITLE := '    avp$create_real_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new real type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_real_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         real_value: real;
         minimum_real_value: real;
         maximum_real_value: real;
         integer_display_format: avt$numeric_display_format;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$real_kind;
    default_value.real_value := ^real_value;

{ Initialize the type specification values.

    type_specification.kind := avc$real_kind;
    type_specification.minimum_real_value := ^minimum_real_value;
    type_specification.maximum_real_value := ^maximum_real_value;
    type_specification.real_display_format := ^integer_display_format;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority, avc$change_real_command,
          default_value, type_specification, file_information, status);

  PROCEND avp$create_real_field;
?? TITLE := '    avp$create_ring_privilege_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new ring privilege type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_ring_privilege_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         minimum_ring: ost$ring;
         nominal_ring: ost$ring;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$ring_privilege_kind;
    default_value.minimum_ring := ^minimum_ring;
    default_value.nominal_ring := ^nominal_ring;

{ Initialize the type specification values.

    type_specification.kind := avc$ring_privilege_kind;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority,
          avc$change_ring_privilege_cmd, default_value, type_specification, file_information, status);

  PROCEND avp$create_ring_privilege_field;
?? TITLE := '    avp$create_string_field', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to create a new string type validation
{ field within a validation record.
{
{ DESIGN:
{
{   This interface is only callable by family administrators or above.
{
{   The default values and type specification values are assigned from
{ the input parameters, then, an internal procedure is called that:
{    - initializes the record utility information for the description record
{    - initializes the description for the field
{    - initializes the field utility information for the field
{    - verifies the field for type conformance
{    - creates the field.
{

  PROCEDURE [XDCL, #GATE] avp$create_string_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         string_value: ost$string;
         minimum_string_size: ost$string_size;
         maximum_string_size: ost$string_size;
         change_commands: avt$name_list;
         display_commands: avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < avc$family_admin_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Initialize the default values.

    default_value.kind := avc$string_kind;
    default_value.string_value := ^string_value.value (1, string_value.size);

{ Initialize the type specification values.

    type_specification.kind := avc$string_kind;
    type_specification.minimum_string_size := ^minimum_string_size;
    type_specification.maximum_string_size := ^maximum_string_size;

{ Create the field.

    create_field (field_name, validation_record_name, ^change_commands, ^display_commands, description,
          display_authority, change_authority, manage_authority, delete_authority, avc$change_string_command,
          default_value, type_specification, file_information, status);

  PROCEND avp$create_string_field;
?? TITLE := '    create_field', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the various field creation interfaces to
{ set up the common field information and create the requested field.
{

  PROCEDURE create_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ost$string;
         display_authority: avt$validation_authority;
         change_authority: avt$validation_authority;
         manage_authority: avt$validation_authority;
         delete_authority: avt$validation_authority;
         procedure_name: ost$name;
         default_value: avt$field_value;
         type_specification: avt$type_specification;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      descriptive_text: ^avt$descriptive_text,
      field_kind: avt$field_kind,
      field_utility_information: avt$field_utility_information,
      record_utility_information: ^avt$utility_information,
      utility_information: ^avt$utility_information,
      utility_information_size: integer;

    status.normal := TRUE;

  /create/
    BEGIN

{ Make sure the field doesn't already exist.

    avp$get_validation_field_kind (field_name, validation_record_name, field_kind, file_information, status);
    IF status.normal THEN
      osp$set_status_abnormal ('AV', ave$field_already_exists, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, validation_record_name, status);
      EXIT /create/;
    ELSEIF status.condition <> ave$unknown_field THEN
      EXIT /create/;
    IFEND;
    status.normal := TRUE;

{ Initialize the record utility information change and display commands.

{ The pointers for change and display commands will only be NIL if
{ a capability field is being created (i.e. one standard command is used for
{ all capabilities.

    IF ((change_commands <> NIL) OR (display_commands <> NIL)) THEN

{ Get the current command table information.

      avp$get_desc_utility_info_size (validation_record_name, utility_information_size, file_information,
            status);
      IF NOT status.normal THEN
        EXIT /create/;
      IFEND;
      PUSH record_utility_information: [[REP utility_information_size OF cell,
            REP avc$maximum_name_list_size OF avt$record_utility_info_entry]];
      RESET record_utility_information;
      utility_information_size := #SIZE (record_utility_information^);
      avp$get_desc_utility_info (validation_record_name, record_utility_information, file_information,
            status);
      IF NOT status.normal THEN
        EXIT /create/;
      IFEND;

{ Add the specified change commands to the command table information.

      add_new_record_utility_info_cmd (change_commands^, field_name, procedure_name,
            record_utility_information, status);
      IF NOT status.normal THEN
        EXIT /create/;
      IFEND;

{ Add the specified display commands to the command table information.

      add_new_record_utility_info_cmd (display_commands^, field_name, avc$display_field_value,
            record_utility_information, status);
      IF NOT status.normal THEN
        EXIT /create/;
      IFEND;
    IFEND;

{ Initialize the description.

    descriptive_text := ^description.value (1, description.size);

{ Initialize the field utility information authorities.

    field_utility_information.display_authority := display_authority;
    field_utility_information.change_authority := change_authority;
    field_utility_information.manage_authority := manage_authority;
    field_utility_information.delete_authority := delete_authority;
    field_utility_information.hidden_field := FALSE;

{ Verify values are valid for this type.

    avp$verify_type_conformance (field_name, default_value, type_specification, status);
    IF NOT status.normal THEN
      EXIT /create/;
    IFEND;

{ Sort the record utility information.
{ Note: The sort is after verify type conformance because it
{       will return an error if a duplicate entry is found and
{       any errors from verify type conformance should be first.

    IF ((change_commands <> NIL) OR (display_commands <> NIL)) THEN
      sort_record_utility_information (record_utility_information, utility_information, status);
      IF NOT status.normal THEN
        EXIT /create/;
      IFEND;
    IFEND;

{ Create the field.

    avp$create_field (field_name, validation_record_name, type_specification, default_value,
          descriptive_text, #SEQ (field_utility_information), file_information, status);
    IF NOT status.normal THEN
      EXIT /create/;
    IFEND;

{ Update the record utility command table information.

    IF ((change_commands <> NIL) OR (display_commands <> NIL)) THEN
      avp$change_desc_utility_info (validation_record_name, utility_information, file_information, status);
    IFEND;
    END /create/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_create_field;
      audit_information.create_validation_field.description_record_name_p := ^validation_record_name;
      audit_information.create_validation_field.validation_file_p := ^file_information.file_name;
      audit_information.create_validation_field.field_name_p := ^field_name;
      audit_information.create_validation_field.field_kind := type_specification.kind;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND create_field;
?? OLDTITLE ??
?? TITLE := '  Interfaces to read field descriptions' ??
?? NEWTITLE := '    avp$get_acct_proj_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get an integer type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_acct_proj_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR default_account_name: avt$account_name;
     VAR default_project_name: avt$project_name;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Retrieve the description record that contains the field description for the specified field.

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$account_project_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'account project', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    default_account_name := default_value.account_name^;
    default_project_name := default_value.project_name^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_acct_proj_field_desc;
?? TITLE := '    avp$get_accum_limit_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get an accumulating limit type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_accum_limit_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR job_warning_limit: avt$limit_value;
     VAR job_maximum_limit: avt$limit_value;
     VAR total_limit: avt$limit_value;
     VAR total_accumulation: avt$limit_value;
     VAR limit_name: ost$name;
     VAR job_limits_apply: boolean;
     VAR minimum_job_limit_value: avt$limit_value;
     VAR maximum_job_limit_value: avt$limit_value;
     VAR number_of_limit_update_stats: avt$name_list_size;
     VAR limit_update_statistics: ^sft$limit_update_statistics;
     VAR total_limit_applies: boolean;
     VAR total_limit_stops_login: boolean;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$accumulating_limit_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'accumulating limit', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    job_warning_limit := default_value.job_warning_limit^;
    job_maximum_limit := default_value.job_maximum_limit^;
    total_limit := default_value.total_limit^;
    total_accumulation := default_value.total_accumulation^;

{ Get the type specification values.

    limit_name := type_specification.limit_name^;
    IF limit_name = avc$cp_time_limit_name THEN
      limit_name := avc$cpu_time_limit_name;
    IFEND;
    job_limits_apply := type_specification.job_limits_apply^;

    IF type_specification.limit_update_statistics = NIL THEN
      number_of_limit_update_stats := 0;
    ELSE
      number_of_limit_update_stats := UPPERBOUND (type_specification.limit_update_statistics^);
    IFEND;
    IF limit_update_statistics <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (limit_update_statistics^)) AND (index <= number_of_limit_update_stats) DO
        limit_update_statistics^ [index] := type_specification.limit_update_statistics^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

    minimum_job_limit_value := type_specification.minimum_job_limit_value^;
    maximum_job_limit_value := type_specification.maximum_job_limit_value^;
    total_limit_applies := type_specification.total_limit_applies^;
    total_limit_stops_login := type_specification.total_limit_stops_login^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_accum_limit_field_desc;
?? TITLE := '    avp$get_capability_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a capability type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_capability_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR capability: boolean;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$capability_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'capability', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    capability := default_value.capability^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_capability_field_desc;
?? TITLE := '    avp$get_date_time_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a date time type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_date_time_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR date_time: avt$date_time;
     VAR date_time_range: boolean;
     VAR date_applies: boolean;
     VAR time_applies: boolean;
     VAR date_display_format: clt$date_time_form_string;
     VAR time_display_format: clt$date_time_form_string;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$date_time_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'date_time', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    date_time := default_value.date_time^;

{ Get the type specification values.

    date_time_range := type_specification.date_time_range^;
    date_applies := type_specification.date_applies^;
    time_applies := type_specification.time_applies^;
    IF date_applies THEN
      date_display_format := type_specification.date_display_format^;
    ELSE
      date_display_format := '';
    IFEND;
    IF time_applies THEN
      time_display_format := type_specification.time_display_format^;
    ELSE
      time_display_format := '';
    IFEND;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_date_time_field_desc;
?? TITLE := '    avp$get_file_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a file type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_file_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR file: string (fsc$max_path_size);
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$file_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'file', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    file := default_value.file^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_file_field_desc;

?? TITLE := '    avp$get_integer_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a integer type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_integer_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR integer_value: integer;
     VAR minimum_integer_value: integer;
     VAR maximum_integer_value: integer;
     VAR integer_display_format: avt$numeric_display_format;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$integer_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'integer', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    integer_value := default_value.integer_value^;

{ Get the type specification values.

    minimum_integer_value := type_specification.minimum_integer_value^;
    maximum_integer_value := type_specification.maximum_integer_value^;
    integer_display_format := type_specification.integer_display_format^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_integer_field_desc;

?? TITLE := '    avp$get_job_class_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a job class type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_job_class_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR number_of_job_classes: avt$name_list_size;
     VAR job_classes: ^avt$name_list;
     VAR batch_job_class_default: ost$name;
     VAR interactive_job_class_default: ost$name;
     VAR number_of_common_job_classes: avt$name_list_size;
     VAR common_job_classes: ^avt$name_list;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$job_class_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'job class', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    number_of_job_classes := UPPERBOUND (default_value.job_classes^);
    IF job_classes <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (job_classes^)) AND (index <= number_of_job_classes) DO
        job_classes^ [index] := default_value.job_classes^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

    batch_job_class_default := default_value.batch_job_class_default^;
    interactive_job_class_default := default_value.interactive_job_class_default^;

    number_of_common_job_classes := UPPERBOUND (type_specification.common_job_classes^);
    IF common_job_classes <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (common_job_classes^)) AND (index <= number_of_common_job_classes) DO
        common_job_classes^ [index] := type_specification.common_job_classes^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_job_class_field_desc;
?? TITLE := '    avp$get_labeled_names_field_des', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a labeled_names type field's field description values.
{
{ DESIGN:
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field, and the authority information
{ from the field utility information.

  PROCEDURE [XDCL, #GATE] avp$get_labeled_names_field_des
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
         work_area: ^seq (*);
     VAR labeled_names: ^avt$labeled_names_list;
     VAR number_of_valid_labels: avt$name_list_size;
     VAR valid_labels: ^avt$name_list;
     VAR number_of_valid_names: avt$name_list_size;
     VAR valid_names: ^avt$name_list;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      field_work_area: ^seq (*),
      index: avt$name_list_size,
      type_specification: avt$type_specification,
      work_area_ptr: ^seq (*);

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
    RESET field_work_area;
    get_field_description (field_name, record_name, record_id, field_work_area, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$labeled_names_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'labeled names', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    IF default_value.labeled_names <> NIL THEN
      work_area_ptr := work_area;
      NEXT labeled_names: [1 .. UPPERBOUND (default_value.labeled_names^)] IN work_area_ptr;
      FOR index := 1 TO UPPERBOUND (default_value.labeled_names^) DO
        NEXT labeled_names^ [index].label IN work_area_ptr;
        labeled_names^ [index].label^ := default_value.labeled_names^ [index].label^;

        NEXT labeled_names^ [index].names: [1 .. UPPERBOUND (default_value.labeled_names^ [index].names^)] IN
              work_area_ptr;
        labeled_names^ [index].names^ := default_value.labeled_names^ [index].names^;
      FOREND;
    ELSE
      labeled_names := NIL;
    IFEND;

{ Get the type specification values.

    IF type_specification.valid_labels = NIL THEN
      number_of_valid_labels := 0;
    ELSE
      number_of_valid_labels := UPPERBOUND (type_specification.valid_labels^);
    IFEND;
    IF valid_labels <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (valid_labels^)) AND (index <= number_of_valid_labels) DO
        valid_labels^ [index] := type_specification.valid_labels^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

    IF type_specification.valid_names = NIL THEN
      number_of_valid_names := 0;
    ELSE
      number_of_valid_names := UPPERBOUND (type_specification.valid_names^);
    IFEND;
    IF valid_names <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (valid_names^)) AND (index <= number_of_valid_names) DO
        valid_names^ [index] := type_specification.valid_names^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_labeled_names_field_des;
?? TITLE := '    avp$get_limit_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a limit type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_limit_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR limit_value: avt$limit_value;
     VAR minimum_limit_value: avt$limit_value;
     VAR maximum_limit_value: avt$limit_value;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$limit_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'limit', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    limit_value := default_value.limit_value^;

{ Get the type specification values.

    minimum_limit_value := type_specification.minimum_limit_value^;
    maximum_limit_value := type_specification.maximum_limit_value^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_limit_field_desc;
?? TITLE := '    avp$get_login_pw_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a login password type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_login_pw_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR password: avt$login_password;
     VAR expiration_date: ost$date_time;
     VAR expiration_interval: pmt$time_increment;
     VAR maximum_expiration_interval: pmt$time_increment;
     VAR expiration_warning: pmt$time_increment;
     VAR expiration_change_interval: pmt$time_increment;
     VAR number_of_attributes: avt$name_list_size;
     VAR attributes: ^avt$name_list;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$login_password_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'login password', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    password := default_value.login_password^;
    expiration_date := default_value.login_password_exp_date^;
    expiration_interval := default_value.login_password_exp_interval^;
    maximum_expiration_interval := default_value.login_password_max_exp_interval^;
    expiration_warning := default_value.login_password_exp_warning^;
    expiration_change_interval := default_value.login_password_exp_chg_interval^;

    IF default_value.login_password_attributes = NIL THEN
      number_of_attributes := 0;
    ELSE
      number_of_attributes := UPPERBOUND (default_value.login_password_attributes^);
    IFEND;
    IF attributes <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (attributes^)) AND (index <= number_of_attributes) DO
        attributes^ [index] := default_value.login_password_attributes^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_login_pw_field_desc;

?? TITLE := '    avp$get_name_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a name type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_name_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR number_of_names: avt$name_list_size;
     VAR names: ^avt$name_list;
     VAR minimum_number_of_names: avt$name_list_size;
     VAR maximum_number_of_names: avt$name_list_size;
     VAR number_of_common_names: avt$name_list_size;
     VAR common_names: ^avt$name_list;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$name_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'name', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    IF default_value.names = NIL THEN
      number_of_names := 0;
    ELSE
      number_of_names := UPPERBOUND (default_value.names^);
    IFEND;
    IF names <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (names^)) AND (index <= number_of_names) DO
        names^ [index] := default_value.names^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

{ Get the type specification values.

    minimum_number_of_names := type_specification.minimum_number_of_names^;
    maximum_number_of_names := type_specification.maximum_number_of_names^;

    IF type_specification.common_names = NIL THEN
      number_of_common_names := 0;
    ELSE
      number_of_common_names := UPPERBOUND (type_specification.common_names^);
    IFEND;
    IF common_names <> NIL THEN
      index := 1;
      WHILE (index <= UPPERBOUND (common_names^)) AND (index <= number_of_common_names) DO
        common_names^ [index] := type_specification.common_names^ [index];
        index := index + 1;
      WHILEND;
    IFEND;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_name_field_desc;

?? TITLE := '    avp$get_real_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a real type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_real_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR real_value: real;
     VAR minimum_real_value: real;
     VAR maximum_real_value: real;
     VAR integer_display_format: avt$numeric_display_format;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$real_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'real', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    real_value := default_value.real_value^;

{ Get the type specification values.

    minimum_real_value := type_specification.minimum_real_value^;
    maximum_real_value := type_specification.maximum_real_value^;
    integer_display_format := type_specification.integer_display_format^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_real_field_desc;
?? TITLE := '    avp$get_ring_priv_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a ring privilege type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_ring_priv_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR minimum_ring: ost$ring;
     VAR nominal_ring: ost$ring;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$ring_privilege_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'ring privilege', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    minimum_ring := default_value.minimum_ring^;
    nominal_ring := default_value.nominal_ring^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_ring_priv_field_desc;
?? TITLE := '    avp$get_string_field_desc', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a string type field's field
{ description values.
{
{ DESIGN:
{
{   This is not a protected interface.
{
{   This interface retrieves the default value and type specification information
{ from the description record which contains the field and the authority information
{ from the field utility information.
{

  PROCEDURE [XDCL, #GATE] avp$get_string_field_desc
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
     VAR string_value: ost$string;
     VAR minimum_string_size: ost$string_size;
     VAR maximum_string_size: ost$string_size;
     VAR description: ost$string;
     VAR change_authority: avt$validation_authority;
     VAR delete_authority: avt$validation_authority;
     VAR display_authority: avt$validation_authority;
     VAR manage_authority: avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    get_field_description (field_name, record_name, record_id, {field_work_area=} NIL, description_record,
          default_value, type_specification, description, field_utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field being retrieved is of the type specified.

    IF type_specification.kind <> avc$string_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'string', status);
      RETURN;
    IFEND;

{ Get the default values from the field description.

    IF default_value.string_value = NIL THEN
      string_value.value := ' ';
      string_value.size := 0;
    ELSE
      string_value.value := default_value.string_value^;
      string_value.size := #SIZE (default_value.string_value^);
    IFEND;

{ Get the type specification values.

    minimum_string_size := type_specification.minimum_string_size^;
    maximum_string_size := type_specification.maximum_string_size^;

{ Get the field utility information values.

    change_authority := field_utility_information.change_authority;
    delete_authority := field_utility_information.delete_authority;
    display_authority := field_utility_information.display_authority;
    manage_authority := field_utility_information.manage_authority;

  PROCEND avp$get_string_field_desc;
?? OLDTITLE ??
?? TITLE := '  Interfaces to change field descriptions' ??
?? NEWTITLE := '    avp$change_acct_proj_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_acct_proj_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         account_name: ^avt$account_name;
         project_name: ^avt$project_name;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      current_description: ost$string,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      ignore_status: ost$status,
      key: avt$validation_key,
      member_exists: boolean,
      project_exists: boolean,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (account_name <> NIL) OR (project_name <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$account_project_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'account project', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the account name default value if specified.

      IF account_name <> NIL THEN
        default_value.account_name := account_name;
      IFEND;

{ Change the project name default value if specified.

      IF project_name <> NIL THEN
        default_value.project_name := project_name;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_acct_proj_command, default_value, type_specification, field_utility_information,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Determine if the account and project exist.

      verify_acct_proj_membership (avp$validation_level (), default_value.account_name^,
            default_value.project_name^, osc$null_name, account_exists, project_exists, member_exists,
            file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

{ Return a warning if the default account and or project do not exist.

    IF NOT account_exists THEN
      osp$set_status_abnormal ('AV', ave$account_does_not_exist_warn, default_value.account_name^, status);
    ELSEIF (NOT project_exists) AND (avp$validation_level () = avc$project_level) THEN
      osp$set_status_abnormal ('AV', ave$project_does_not_exist_warn, default_value.project_name^, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, default_value.account_name^, status);
    IFEND;

  PROCEND avp$change_acct_proj_field;
?? TITLE := '    avp$change_accum_limit_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_accum_limit_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         job_warning_limit: ^avt$limit_value;
         job_maximum_limit: ^avt$limit_value;
         total_limit: ^avt$limit_value;
         limit_name: ^ost$name;
         job_limits_apply: ^boolean;
         limit_update_statistics: ^sft$limit_update_statistics;
         minimum_job_limit_value: ^avt$limit_value;
         maximum_job_limit_value: ^avt$limit_value;
         total_limit_applies: ^boolean;
         total_limit_stops_login: ^boolean;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (job_warning_limit <> NIL) OR (job_maximum_limit <> NIL) OR (total_limit <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$accumulating_limit_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'limit', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the job warning limit if specified.

      IF job_warning_limit <> NIL THEN
        default_value.job_warning_limit := job_warning_limit;
      IFEND;

{ Change the job maximum limit if specified.

      IF job_maximum_limit <> NIL THEN
        default_value.job_maximum_limit := job_maximum_limit;
      IFEND;

{ Change the total limit if specified.

      IF total_limit <> NIL THEN
        default_value.total_limit := total_limit;
      IFEND;

{ Change the limit name if specified.
{ The limit name for system defined limits may not be changed.

      IF limit_name <> NIL THEN
        IF field_utility_information.delete_authority <> avc$system_authority THEN
          type_specification.limit_name := limit_name;
        ELSE
          IF limit_name^ <> type_specification.limit_name^ THEN
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
            EXIT /change/;
          IFEND;
        IFEND;
      IFEND;

{ Change the job limits apply value if specified.
{ The job limits apply value of system defined limits may not be changed.

      IF job_limits_apply <> NIL THEN
        IF field_utility_information.delete_authority <> avc$system_authority THEN
          type_specification.job_limits_apply := job_limits_apply;
        ELSE
          IF job_limits_apply^ <> type_specification.job_limits_apply^ THEN
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
            EXIT /change/;
          IFEND;
        IFEND;
      IFEND;

{ Change the limit update statistics values if specified.

      IF limit_update_statistics <> NIL THEN

{ A statistic code of zero signifies that the current list should be removed.

        IF limit_update_statistics^ [1].statistic_code = 0 THEN
          type_specification.limit_update_statistics := NIL;
        ELSEIF field_utility_information.delete_authority <> avc$system_authority THEN
          type_specification.limit_update_statistics := limit_update_statistics;
        ELSE
          osp$set_status_condition (ave$insufficient_authority, status);
          EXIT /change/;
        IFEND;
      IFEND;

{ Change the minimum job limit value if specified.

      IF minimum_job_limit_value <> NIL THEN
        type_specification.minimum_job_limit_value := minimum_job_limit_value;
      IFEND;

{ Change the maximum job limit value if specified.

      IF maximum_job_limit_value <> NIL THEN
        type_specification.maximum_job_limit_value := maximum_job_limit_value;
      IFEND;

{ Change the total limit applies value if specified.

      IF total_limit_applies <> NIL THEN
        type_specification.total_limit_applies := total_limit_applies;
      IFEND;

{ Change the total limit stops login value if specified.

      IF total_limit_stops_login <> NIL THEN
        type_specification.total_limit_stops_login := total_limit_stops_login;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_accum_limit_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_accum_limit_field;
?? TITLE := '    avp$change_capability_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_capability_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         capability: ^boolean;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (capability <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$capability_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'capability', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the capability value if specified.

      IF capability <> NIL THEN
        default_value.capability := capability;
      IFEND;

      change_field (field_name, validation_record_name, NIL, NIL, description, current_description,
            display_authority, change_authority, manage_authority, delete_authority,
            avc$change_capability_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_capability_field;
?? TITLE := '    avp$change_date_time_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_date_time_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         date_time: ^avt$date_time;
         date_applies: ^boolean;
         time_applies: ^boolean;
         date_display_format: ^clt$date_time_form_string;
         time_display_format: ^clt$date_time_form_string;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      current_description: ost$string,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (date_time <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$date_time_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'date time', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the date time value if specified.

      IF date_time <> NIL THEN
        default_value.date_time := date_time;
      IFEND;

{ Change the date applies value if specified.

      IF date_applies <> NIL THEN
        type_specification.date_applies := date_applies;
      IFEND;

{ Change the time applies value if specified.

      IF time_applies <> NIL THEN
        type_specification.time_applies := time_applies;
      IFEND;

{ Change the date display format value if specified.

      IF date_display_format <> NIL THEN
        type_specification.date_display_format := date_display_format;
      IFEND;

{ Change the time display format if specified.

      IF time_display_format <> NIL THEN
        type_specification.time_display_format := time_display_format;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_date_time_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_date_time_field;
?? TITLE := '    avp$change_file_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_file_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         file: ^fst$file_reference;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (file <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$file_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'file', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the file value if specified.

      IF file <> NIL THEN
        default_value.file := file;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_file_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_file_field;
?? TITLE := '    avp$change_integer_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_integer_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         integer_value: ^integer;
         minimum_integer_value: ^integer;
         maximum_integer_value: ^integer;
         integer_display_format: ^avt$numeric_display_format;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (integer_value <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$integer_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'integer', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the integer value if specified.

      IF integer_value <> NIL THEN
        default_value.integer_value := integer_value;
      IFEND;

{ Change the minimum integer value if specified.

      IF minimum_integer_value <> NIL THEN
        type_specification.minimum_integer_value := minimum_integer_value;
      IFEND;

{ Change the maximum integer value if specified.

      IF maximum_integer_value <> NIL THEN
        type_specification.maximum_integer_value := maximum_integer_value;
      IFEND;

{ Change the integer display format value if specified.

      IF integer_display_format <> NIL THEN
        type_specification.integer_display_format := integer_display_format;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
           current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_integer_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_integer_field;
?? TITLE := '    avp$change_job_class_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_job_class_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         add_job_classes: ^avt$name_list;
         delete_job_classes: ^avt$name_list;
         batch_job_class_default: ^ost$name;
         interactive_job_class_default: ^ost$name;
         add_common_job_classes: ^avt$name_list;
         delete_common_job_classes: ^avt$name_list;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      index: 1 .. avc$maximum_name_list_size,
      job_class_list: array [1 .. avc$maximum_name_list_size] of ost$name,
      number_of_job_classes: 1 .. avc$maximum_name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (add_job_classes <> NIL) OR (delete_job_classes <> NIL) OR
          (batch_job_class_default <> NIL) OR (interactive_job_class_default <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$job_class_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'job class', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Initialize a temporary array for holding the new list of job classes.

      FOR index := 1 TO avc$maximum_name_list_size DO
        job_class_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of job classes to the temporary array.

      FOR index := 1 TO UPPERBOUND (default_value.job_classes^) DO
        job_class_list [index] := default_value.job_classes^ [index];
      FOREND;
      number_of_job_classes := UPPERBOUND (default_value.job_classes^);

{ Delete any specified job classes from the temporary array.

      IF delete_job_classes <> NIL THEN
        delete_names_from_name_list (delete_job_classes, 'delete_job_classes', job_class_list,
              number_of_job_classes, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Add any specified job classes to the temporary array.

      IF add_job_classes <> NIL THEN
        add_names_to_name_list (add_job_classes, 'add_job_classes', job_class_list, number_of_job_classes,
              status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Move the temporary array to the job classes field.

      PUSH default_value.job_classes: [1 .. number_of_job_classes];
      FOR index := 1 TO number_of_job_classes DO
        default_value.job_classes^ [index] := job_class_list [index];
      FOREND;

{ Change the batch job class default value if specified.

      IF batch_job_class_default <> NIL THEN
        default_value.batch_job_class_default := batch_job_class_default;
      IFEND;

{ Change the interactive job class default value if specified.

      IF interactive_job_class_default <> NIL THEN
        default_value.interactive_job_class_default := interactive_job_class_default;
      IFEND;

{ Initialize a temporary array for holding the new list of common job classes.

      FOR index := 1 TO avc$maximum_name_list_size DO
        job_class_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of common job classes to the temporary array.

      FOR index := 1 TO UPPERBOUND (type_specification.common_job_classes^) DO
        job_class_list [index] := type_specification.common_job_classes^ [index];
      FOREND;
      number_of_job_classes := UPPERBOUND (type_specification.common_job_classes^);

{ Delete any specified job classes from the temporary array.

      IF delete_common_job_classes <> NIL THEN
        delete_names_from_name_list (delete_common_job_classes, 'delete_common_job_classes', job_class_list,
              number_of_job_classes, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Add any specified job classes to the temporary array.

      IF add_common_job_classes <> NIL THEN
        add_names_to_name_list (add_common_job_classes, 'add_common_job_classes', job_class_list,
              number_of_job_classes, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Move the temporary array to the common job classes field.

      PUSH type_specification.common_job_classes: [1 .. number_of_job_classes];
      FOR index := 1 TO number_of_job_classes DO
        type_specification.common_job_classes^ [index] := job_class_list [index];
      FOREND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_job_class_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_job_class_field;
?? TITLE := '    avp$change_labeled_names_field', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_labeled_names_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         add_labeled_names: ^avt$labeled_names_list;
         delete_labeled_names: ^avt$labeled_names_list;
         add_valid_labels: ^avt$name_list;
         delete_valid_labels: ^avt$name_list;
         add_valid_names: ^avt$name_list;
         delete_valid_names: ^avt$name_list;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      current_description: ost$string,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      index1: 1 .. avc$maximum_name_list_size,
      labeled_names: ^avt$labeled_names_list,
      name_list: ^avt$name_list,
      number_of_names: 1 .. avc$maximum_name_list_size,
      type_specification: avt$type_specification,
      field_work_area: ^seq (*),
      work_area: ^seq (*);

    status.normal := TRUE;
    changed_default_value := (add_labeled_names <> NIL) OR (delete_labeled_names <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
      RESET field_work_area;
      get_field_description (field_name, validation_record_name, osc$null_name, field_work_area,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

  { Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$labeled_names_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'labeled names', status);
        EXIT /change/;
      IFEND;

  { Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

  { Change the labeled names default value.

      PUSH work_area: [[REP avc$max_template_record_size OF cell]];
      RESET work_area;
      change_labeled_names (add_labeled_names, delete_labeled_names, default_value, work_area,
            labeled_names, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

  { Move the temporary labeled names array to the labeled names field.

      PUSH default_value.labeled_names: [1 .. UPPERBOUND (labeled_names^)];
      FOR index1 := 1 TO UPPERBOUND (labeled_names^) DO
        default_value.labeled_names^ [index1] := labeled_names^ [index1];
      FOREND;

  { Initialize a temporary array for holding the new list of valid labels.

      PUSH name_list: [1 .. avc$maximum_name_list_size];
      FOR index1 := 1 TO avc$maximum_name_list_size DO
        name_list^ [index1] := osc$null_name;
      FOREND;

  { Copy the current list of valid labels to the temporary array.

      FOR index1 := 1 TO UPPERBOUND (type_specification.valid_labels^) DO
        name_list^ [index1] := type_specification.valid_labels^ [index1];
      FOREND;
      number_of_names := UPPERBOUND (type_specification.valid_labels^);

  { Delete any specified valid labels from the temporary array.

      IF delete_valid_labels <> NIL THEN
        delete_names_from_name_list (delete_valid_labels, 'delete_valid_labels', name_list^,
              number_of_names, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

  { Add any specified valid labels to the temporary array.

      IF add_valid_labels <> NIL THEN
        add_names_to_name_list (add_valid_labels, 'add_valid_labels', name_list^, number_of_names,
              status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

  { Move the temporary array to the valid labels field.

      PUSH type_specification.valid_labels: [1 .. number_of_names];
      FOR index1 := 1 TO number_of_names DO
        type_specification.valid_labels^ [index1] := name_list^ [index1];
      FOREND;

  { Initialize a temporary array for holding the new list of valid labels.

      FOR index1 := 1 TO avc$maximum_name_list_size DO
        name_list^ [index1] := osc$null_name;
      FOREND;

  { Copy the current list of valid names to the temporary array.

      FOR index1 := 1 TO UPPERBOUND (type_specification.valid_names^) DO
        name_list^ [index1] := type_specification.valid_names^ [index1];
      FOREND;
      number_of_names := UPPERBOUND (type_specification.valid_names^);

  { Delete any specified valid names from the temporary array.

      IF delete_valid_names <> NIL THEN
        delete_names_from_name_list (delete_valid_names, 'delete_valid_names', name_list^,
              number_of_names, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

  { Add any specified valid names to the temporary array.

      IF add_valid_names <> NIL THEN
        add_names_to_name_list (add_valid_names, 'add_valid_names', name_list^, number_of_names,
              status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

  { Move the temporary array to the valid names field.

      PUSH type_specification.valid_names: [1 .. number_of_names];
      FOR index1 := 1 TO number_of_names DO
        type_specification.valid_names^ [index1] := name_list^ [index1];
      FOREND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_labeled_names_cmd, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_labeled_names_field;
?? TITLE := '    avp$change_limit_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_limit_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         limit_value: ^avt$limit_value;
         minimum_limit_value: ^avt$limit_value;
         maximum_limit_value: ^avt$limit_value;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (limit_value <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$limit_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'limit', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the limit value if specified.

      IF limit_value <> NIL THEN
        default_value.limit_value := limit_value;
      IFEND;

{ Change the minimum limit value if specified.

      IF minimum_limit_value <> NIL THEN
        type_specification.minimum_limit_value := minimum_limit_value;
      IFEND;

{ Change the maximum limit value if specified.

      IF maximum_limit_value <> NIL THEN
        type_specification.maximum_limit_value := maximum_limit_value;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_limit_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_limit_field;
?? TITLE := '    avp$change_login_password_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_login_password_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         login_password: ^avt$login_password;
         login_password_exp_date: ^ost$date_time;
         login_password_exp_interval: ^pmt$time_increment;
         login_password_max_exp_interval: ^pmt$time_increment;
         login_password_exp_warning: ^pmt$time_increment;
         login_password_exp_chg_interval: ^pmt$time_increment;
         add_password_attributes: ^avt$name_list;
         delete_password_attributes: ^avt$name_list;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      index: 1 .. avc$maximum_name_list_size,
      number_of_password_attributes: 1 .. avc$maximum_name_list_size,
      password_attribute_list: array [1 .. avc$maximum_name_list_size] of ost$name,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (login_password <> NIL) OR (login_password_exp_date <> NIL) OR
          (login_password_exp_interval <> NIL) OR (login_password_max_exp_interval <> NIL) OR
          (login_password_exp_warning <> NIL) OR (login_password_exp_chg_interval <> NIL) OR
          (add_password_attributes <> NIL) OR (delete_password_attributes <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$login_password_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'login password', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the login password value if specified.

      IF login_password <> NIL THEN
        default_value.login_password := login_password;
      IFEND;

{ Change the expiration date value if specified.

      IF login_password_exp_date <> NIL THEN
        default_value.login_password_exp_date := login_password_exp_date;
      IFEND;

{ Change the expiration interval if specified.

      IF login_password_exp_interval <> NIL THEN
        default_value.login_password_exp_interval := login_password_exp_interval;
      IFEND;

{ Change the maximum expiration interval if specified.

      IF login_password_max_exp_interval <> NIL THEN
        default_value.login_password_max_exp_interval := login_password_max_exp_interval;
      IFEND;

{ Change the expiration warning interval if specified.

      IF login_password_exp_warning <> NIL THEN
        default_value.login_password_exp_warning := login_password_exp_warning;
      IFEND;

{ Change the expired password change interval if specified.

      IF login_password_exp_chg_interval <> NIL THEN
        default_value.login_password_exp_chg_interval := login_password_exp_chg_interval;
      IFEND;

{ Initialize a temporary array for holding the new list of password attributes.

      FOR index := 1 TO avc$maximum_name_list_size DO
        password_attribute_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of password attributes to the temporary array.

      FOR index := 1 TO UPPERBOUND (default_value.login_password_attributes^) DO
        password_attribute_list [index] := default_value.login_password_attributes^ [index];
      FOREND;
      number_of_password_attributes := UPPERBOUND (default_value.login_password_attributes^);

{ Delete any specified password attributes from the temporary array.

      IF delete_password_attributes <> NIL THEN
        delete_names_from_name_list (delete_password_attributes, 'delete_password_attributes',
              password_attribute_list, number_of_password_attributes, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Add any specified password attributes to the temporary array.

      IF add_password_attributes <> NIL THEN
        add_names_to_name_list (add_password_attributes, 'add_password_attributes', password_attribute_list,
              number_of_password_attributes, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Move the temparary array to the password attributes field.

      PUSH default_value.login_password_attributes: [1 .. number_of_password_attributes];
      FOR index := 1 TO number_of_password_attributes DO
        default_value.login_password_attributes^ [index] := password_attribute_list [index];
      FOREND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_login_password_cmd, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_login_password_field;
?? TITLE := '    avp$change_name_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_name_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         add_names: ^avt$name_list;
         delete_names: ^avt$name_list;
         minimum_number_of_names: ^avt$name_list_size;
         maximum_number_of_names: ^avt$name_list_size;
         add_common_names: ^avt$name_list;
         delete_common_names: ^avt$name_list;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      index: 1 .. avc$maximum_name_list_size,
      number_of_common_names: 1 .. avc$maximum_name_list_size,
      number_of_names: 1 .. avc$maximum_name_list_size,
      name_list: array [1 .. avc$maximum_name_list_size] of ost$name,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (add_names <> NIL) OR (delete_names<> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

    IF type_specification.kind <> avc$name_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'name', status);
      EXIT /change/;
    IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Initialize a temporary array for holding the new list of names.

      FOR index := 1 TO avc$maximum_name_list_size DO
        name_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of names to the temporary array.

      FOR index := 1 TO UPPERBOUND (default_value.names^) DO
        name_list [index] := default_value.names^ [index];
      FOREND;
      number_of_names := UPPERBOUND (default_value.names^);

{ Delete any specified names from the temporary array.

      IF delete_names <> NIL THEN
        delete_names_from_name_list (delete_names, 'delete_names', name_list, number_of_names, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Add any specified names to the temporary array.

      IF add_names <> NIL THEN
        add_names_to_name_list (add_names, 'add_names', name_list, number_of_names, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Move the temporary array to the name field.

      PUSH default_value.names: [1 .. number_of_names];
      FOR index := 1 TO number_of_names DO
        default_value.names^ [index] := name_list [index];
      FOREND;

{ Change the minimum number of names value if specified.

      IF minimum_number_of_names <> NIL THEN
        type_specification.minimum_number_of_names := minimum_number_of_names;
      IFEND;

{ Change the maximum number of names if specified.

      IF maximum_number_of_names <> NIL THEN
        type_specification.maximum_number_of_names := maximum_number_of_names;
      IFEND;

{ Initialize a temporary array for holding the new list of common names.

      FOR index := 1 TO avc$maximum_name_list_size DO
        name_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of common names to the temporary array.

      FOR index := 1 TO UPPERBOUND (type_specification.common_names^) DO
        name_list [index] := type_specification.common_names^ [index];
      FOREND;
      number_of_common_names := UPPERBOUND (type_specification.common_names^);

{ Delete any specified common names from the temporary array.

      IF delete_common_names <> NIL THEN
        delete_names_from_name_list (delete_common_names, 'delete_common_names', name_list,
              number_of_common_names, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Add any specified common names to the temporary array.

      IF add_common_names <> NIL THEN
        add_names_to_name_list (add_common_names, 'add_common_names', name_list, number_of_common_names,
              status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Move the temporary array to the common names field.

      PUSH type_specification.common_names: [1 .. number_of_common_names];
      FOR index := 1 TO number_of_common_names DO
        type_specification.common_names^ [index] := name_list [index];
      FOREND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_name_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_name_field;
?? TITLE := '    avp$change_real_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_real_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         real_value: ^real;
         minimum_real_value: ^real;
         maximum_real_value: ^real;
         real_display_format: ^avt$numeric_display_format;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (real_value <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$real_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'real', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the real value if specified.

      IF real_value <> NIL THEN
        default_value.real_value := real_value;
      IFEND;

{ Change the minimum real value if specified.

      IF minimum_real_value <> NIL THEN
        type_specification.minimum_real_value := minimum_real_value;
      IFEND;

{ Change the maximum real value if specified.

      IF maximum_real_value <> NIL THEN
        type_specification.maximum_real_value := maximum_real_value;
      IFEND;

{ Change the real display format if specified.

      IF real_display_format <> NIL THEN
        type_specification.real_display_format := real_display_format;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_real_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_real_field;
?? TITLE := '    avp$change_ring_privilege_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_ring_privilege_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         minimum_ring: ^ost$ring;
         nominal_ring: ^ost$ring;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (minimum_ring <> NIL) OR (nominal_ring <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$ring_privilege_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'ring privilege', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the minimum ring value if specified.

      IF minimum_ring <> NIL THEN
        default_value.minimum_ring := minimum_ring;
      IFEND;

{ Change the nominal ring value if specified.

      IF nominal_ring <> NIL THEN
        default_value.nominal_ring := nominal_ring;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_ring_privilege_cmd, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_ring_privilege_field;
?? TITLE := '    avp$change_string_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change an existing validation field's field
{ definition values.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the manage authority for the specified field.
{
{   The field being changed is verified to be of the type specified.
{
{   The default values and type specification values are updated.
{
{   A local procedure is called that:
{    - updates the record utility information for the description record
{    - updates the description for the field
{    - updates the field utility information for the field
{    - verifies the field for type conformance
{    - changes the field.
{

  PROCEDURE [XDCL, #GATE] avp$change_string_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         string_value: ^ost$string;
         minimum_string_size: ^ost$string_size;
         maximum_string_size: ^ost$string_size;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      changed_default_value: boolean,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      descriptive_text: ^avt$descriptive_text,
      field_utility_information: avt$field_utility_information,
      type_specification: avt$type_specification;

    status.normal := TRUE;
    changed_default_value := (string_value <> NIL);

    #CALLER_ID (caller_id);

{ Retrieve the description record that contains the field description for the specified field.

  /change/
    BEGIN
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Verify that the field being changed is of the type specified.

      IF type_specification.kind <> avc$string_kind THEN
        osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, 'string', status);
        EXIT /change/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.manage_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change/;
      IFEND;

{ Change the string value if specified.

      IF string_value <> NIL THEN
        default_value.string_value := ^string_value^.value (1, string_value^.size);
      IFEND;

{ Change the minimum string size if specified.

      IF minimum_string_size <> NIL THEN
        type_specification.minimum_string_size := minimum_string_size;
      IFEND;

{ Change the maximum string size if specified.

      IF maximum_string_size <> NIL THEN
        type_specification.maximum_string_size := maximum_string_size;
      IFEND;

      change_field (field_name, validation_record_name, change_commands, display_commands, description,
            current_description, display_authority, change_authority, manage_authority, delete_authority,
            avc$change_string_command, default_value, type_specification, field_utility_information,
            file_information, status);
    END /change/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      emit_chg_field_audit_statistic (validation_record_name, file_information.file_name, field_name,
            changed_default_value, change_authority, display_authority, manage_authority, status);
    IFEND;

  PROCEND avp$change_string_field;
?? TITLE := '    change_field', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the previous field change interfaces to
{ change the common field information and update the requested field.
{

  PROCEDURE change_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
         description: ^ost$string;
         current_description: ost$string;
         display_authority: ^avt$validation_authority;
         change_authority: ^avt$validation_authority;
         manage_authority: ^avt$validation_authority;
         delete_authority: ^avt$validation_authority;
         procedure_name: ost$name;
         default_value: avt$field_value;
         type_specification: avt$type_specification;
     VAR field_utility_information: avt$field_utility_information;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      descriptive_text: ^avt$descriptive_text,
      record_utility_information: ^avt$utility_information,
      utility_information: ^avt$utility_information,
      utility_information_size: integer;

    status.normal := TRUE;

{ Retrieve the change and display command information from the record
{ utility information if specified.

    IF ((change_commands <> NIL) OR (display_commands <> NIL)) THEN
      avp$get_desc_utility_info_size (validation_record_name, utility_information_size, file_information,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      PUSH record_utility_information: [[REP utility_information_size OF cell,
            REP avc$maximum_name_list_size OF avt$record_utility_info_entry]];
      RESET record_utility_information;
      utility_information_size := #SIZE (record_utility_information^);
      avp$get_desc_utility_info (validation_record_name, record_utility_information, file_information,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Change the change commands if specified.

    IF change_commands <> NIL THEN
      delete_record_utility_info_cmd (field_name, procedure_name, record_utility_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      add_new_record_utility_info_cmd (change_commands^, field_name, procedure_name,
            record_utility_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Change the display commands if specified.

    IF display_commands <> NIL THEN
      delete_record_utility_info_cmd (field_name, avc$display_field_value, record_utility_information,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      add_new_record_utility_info_cmd (display_commands^, field_name, avc$display_field_value,
            record_utility_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Change the description if specified.

    IF description <> NIL THEN
      descriptive_text := ^description^.value (1, description^.size);
    ELSE
      descriptive_text := ^current_description.value (1, current_description.size);
    IFEND;

{ Change the display authority if specified.

    IF display_authority <> NIL THEN
      field_utility_information.display_authority := display_authority^;
    IFEND;

{ Change the change authority if specified.

    IF change_authority <> NIL THEN
      field_utility_information.change_authority := change_authority^;
    IFEND;

{ Change the manage authority if specified.

    IF manage_authority <> NIL THEN
      field_utility_information.manage_authority := manage_authority^;
    IFEND;

{ Change the delete authority if specified.

    IF delete_authority <> NIL THEN
      field_utility_information.delete_authority := delete_authority^;
    IFEND;

{ Verify values are valid for this type.

    avp$verify_type_conformance (field_name, default_value, type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Sort the record utility information.
{ Note: The sort is after verify type conformance because it
{       will return an error if a duplicate entry is found and
{       any errors from verify type conformance should be first.

    IF ((change_commands <> NIL) OR (display_commands <> NIL)) THEN
      sort_record_utility_information (record_utility_information, utility_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Change the field.

    avp$change_field (field_name, validation_record_name, type_specification, default_value,
          descriptive_text, #SEQ (field_utility_information), file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Update the record utility command table information.

    IF ((change_commands <> NIL) OR (display_commands <> NIL)) THEN
      avp$change_desc_utility_info (validation_record_name, utility_information, file_information, status);
    IFEND;

  PROCEND change_field;
?? OLDTITLE ??
?? TITLE := '  Interfaces to delete, restore and change the name of validation fields' ??
?? NEWTITLE := '    avp$change_val_field_name', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the name of a validation field.
{
{ DESIGN:
{
{   This interface is only callable by callers with authority equal to or above
{ the delete authority for the specified field.  The delete authority is used
{ instead of the manage authority because changing the name of a field is
{ essentially equivalent to deleting the field.
{
{   The command table information in the record utility information is update
{ along with the field name change.
{

  PROCEDURE [XDCL, #GATE] avp$change_val_field_name
    (    field_name: ost$name;
         validation_record_name: ost$name;
         new_field_name: ost$name;
         change_commands: ^avt$name_list;
         display_commands: ^avt$name_list;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      change_command_processor: ost$name,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      field_utility_information: avt$field_utility_information,
      field_work_area: ^seq (*),
      record_utility_information: ^avt$utility_information,
      type_specification: avt$type_specification,
      utility_information: ^avt$utility_information,
      utility_information_size: integer;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

  /change_field_name/
    BEGIN

{ Retrieve the delete authority from the field utility information.

      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;
      PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
      RESET field_work_area;
      get_field_description (field_name, validation_record_name, osc$null_name, field_work_area,
            description_record, default_value, type_specification, current_description,
            field_utility_information, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$field_was_deleted THEN
          status.normal := TRUE;
        ELSE
          EXIT /change_field_name/;
        IFEND;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
      IF caller_authority < field_utility_information.delete_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /change_field_name/;
      IFEND;

{ Get the record utility information command table information.

      avp$get_desc_utility_info_size (validation_record_name, utility_information_size, file_information,
            status);
      IF NOT status.normal THEN
        EXIT /change_field_name/;
      IFEND;
      PUSH record_utility_information: [[REP utility_information_size OF cell,
            REP avc$maximum_name_list_size OF avt$record_utility_info_entry]];
      RESET record_utility_information;
      utility_information_size := #SIZE (record_utility_information^);
      avp$get_desc_utility_info (validation_record_name, record_utility_information, file_information,
            status);
      IF NOT status.normal THEN
        EXIT /change_field_name/;
      IFEND;

      IF (change_commands <> NIL) AND (display_commands <> NIL) THEN
        IF type_specification.kind <> avc$capability_kind THEN

{ Remove the command table entries related to the old field name.

          delete_record_utility_info_cmd (field_name, avc$display_field_value, record_utility_information,
                status);
          IF NOT status.normal THEN
            EXIT /change_field_name/;
          IFEND;

          CASE type_specification.kind OF
          = avc$account_project_kind =
           change_command_processor :=  avc$change_acct_proj_command;
          = avc$accumulating_limit_kind =
            change_command_processor :=  avc$change_accum_limit_command;
          = avc$date_time_kind =
            change_command_processor :=  avc$change_date_time_command;
          = avc$file_kind =
            change_command_processor :=  avc$change_file_command;
          = avc$integer_kind =
            change_command_processor :=  avc$change_integer_command;
          = avc$job_class_kind =
            change_command_processor :=  avc$change_job_class_command;
          = avc$limit_kind =
            change_command_processor :=  avc$change_limit_command;
          = avc$login_password_kind =
            change_command_processor :=  avc$change_login_password_cmd;
          = avc$name_kind =
            change_command_processor :=  avc$change_name_command;
          = avc$real_kind =
            change_command_processor :=  avc$change_real_command;
          = avc$ring_privilege_kind =
            change_command_processor :=  avc$change_ring_privilege_cmd;
          = avc$string_kind =
            change_command_processor :=  avc$change_string_command;
          ELSE
            change_command_processor := osc$null_name;
          CASEND;

          delete_record_utility_info_cmd (field_name, change_command_processor, record_utility_information,
                status);
          IF NOT status.normal THEN
            EXIT /change_field_name/;
          IFEND;

{ Add command table entries for the new field name.

          add_new_record_utility_info_cmd (display_commands^, new_field_name, avc$display_field_value,
                record_utility_information, status);
          IF NOT status.normal THEN
            EXIT /change_field_name/;
          IFEND;

          add_new_record_utility_info_cmd (change_commands^, new_field_name, change_command_processor,
                record_utility_information, status);
          IF NOT status.normal THEN
            EXIT /change_field_name/;
          IFEND;
        IFEND;
      ELSE

{ Change the field name within the command table information.

        change_utility_info_field_name (field_name, new_field_name, record_utility_information, status);
        IF NOT status.normal THEN
          EXIT /change_field_name/;
        IFEND;
      IFEND;

{ Sort the updated command table.

      sort_record_utility_information (record_utility_information, utility_information, status);
      IF NOT status.normal THEN
        EXIT /change_field_name/;
      IFEND;

{ NOTE: The order of the remaining code must not be changed so
{       that the command table remains in synch with the fields.

{ Change the validation field name.

      avp$change_field_name (field_name, validation_record_name, new_field_name, file_information, status);
      IF NOT status.normal THEN
        EXIT /change_field_name/;
      IFEND;

{ Rewrite the record utility information command table information.

      avp$change_desc_utility_info (validation_record_name, utility_information, file_information,
          status);
    END /change_field_name/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_change_field_name;
      audit_information.change_val_field_name.description_record_name_p := ^validation_record_name;
      audit_information.change_val_field_name.validation_file_p := ^file_information.file_name;
      audit_information.change_val_field_name.original_field_name_p := ^field_name;
      audit_information.change_val_field_name.new_field_name_p := ^new_field_name;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$change_val_field_name;
?? TITLE := '    avp$delete_validation_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to logically delete a validation field.
{
{ DESIGN:
{
{    This interface is only callable by callers with authority equal to or
{ above the delete authority for the specified field.
{

  PROCEDURE [XDCL, #GATE] avp$delete_validation_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      current_description: ost$string,
      field_utility_information: avt$field_utility_information,
      field_work_area: ^seq (*),
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

  /delete_field/
    BEGIN

{ Retrieve the delete authority from the field utility information.

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
    RESET field_work_area;
    get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
          description_record, default_value, type_specification, current_description,
          field_utility_information, file_information, status);
    IF NOT status.normal THEN
      EXIT /delete_field/;
    IFEND;

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < field_utility_information.delete_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      EXIT /delete_field/;
    IFEND;

    avp$delete_field (field_name, validation_record_name, file_information, status);
    END /delete_field/;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_delete_field;
      audit_information.delete_validation_field.description_record_name_p := ^validation_record_name;
      audit_information.delete_validation_field.validation_file_p := ^file_information.file_name;
      audit_information.delete_validation_field.field_name_p := ^field_name;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND avp$delete_validation_field;
?? TITLE := '    avp$restore_validation_field', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to restore a previously deleted validation field.
{
{ DESIGN:
{
{    This interface is only callable by callers with authority equal to or
{ above the delete authority for the specified field.
{

  PROCEDURE [XDCL, #GATE] avp$restore_validation_field
    (    field_name: ost$name;
         validation_record_name: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      current_description: ost$string,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      field_utility_information: avt$field_utility_information,
      field_work_area: ^seq (*),
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Retrieve the delete authority from the field utility information.

    PUSH description_record: [[REP avc$max_template_record_size OF cell]];
    RESET description_record;
    PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
    RESET field_work_area;
    get_field_description (field_name, validation_record_name, osc$null_name, {field_work_area=} NIL,
          description_record, default_value, type_specification, current_description,
          field_utility_information, file_information, status);
    IF NOT status.normal THEN
      IF status.condition = ave$field_was_deleted THEN
        status.normal := TRUE;
      ELSE
        RETURN;
      IFEND;
    IFEND;

{ Verify that the caller has the required authority.

    determine_caller_authority (caller_id, NIL, NIL, NIL, NIL, NIL, caller_authority);
    IF caller_authority < field_utility_information.delete_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Restore the field.

    avp$restore_field (field_name, validation_record_name, file_information, status);

  PROCEND avp$restore_validation_field;
?? OLDTITLE ??
?? TITLE := '  Interfaces to change field values' ??
?? NEWTITLE := '    avp$change_acct_proj_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of an account project type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{
{   A warning status is returned if the account and/or project do not exist in
{ the validation file or if the user is not a member of the account or project,
{ when the system validation level is set to account or project.
{

  PROCEDURE [XDCL, #GATE] avp$change_acct_proj_value
    (    field_name: ost$name;
         account_name: ^avt$account_name;
         project_name: ^avt$project_name;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      account_exists: boolean,
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      ignore_status: ost$status,
      key: avt$validation_key,
      project_exists: boolean,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification,
      valid_account: boolean,
      valid_member: boolean,
      valid_project: boolean;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change account name if specified.

      IF account_name <> NIL THEN
        NEXT field_value_info.account_name IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.account_name^ := account_name^;
      IFEND;

{ Change project name if specified.

      IF project_name <> NIL THEN
        NEXT field_value_info.project_name IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.project_name^ := project_name^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;

{ Verify that the user is a member of the account and/or project.

      verify_acct_proj_membership (avp$validation_level (), field_value_info.account_name^,
            field_value_info.project_name^, validation_record_info^.key.user_name, valid_account,
            valid_project, valid_member, file_information, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      IF NOT valid_member THEN
        IF NOT valid_account THEN
          osp$set_status_abnormal ('AV', ave$account_does_not_exist_warn, field_value_info.account_name^,
                status);
        ELSEIF NOT valid_project THEN
          osp$set_status_abnormal ('AV', ave$project_does_not_exist_warn, field_value_info.project_name^,
                status);
          osp$append_status_parameter (osc$status_parameter_delimiter, field_value_info.account_name^,
                status);
        ELSEIF avp$validation_level () = avc$account_level THEN
          osp$set_status_abnormal ('AV', ave$acc_mem_does_not_exist_warn,
                validation_record_info^.key.user_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, field_value_info.account_name^,
                status);
        ELSE
          osp$set_status_abnormal ('AV', ave$member_does_not_exist_warn,
                validation_record_info^.key.user_name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter, field_value_info.account_name^,
                status);
          osp$append_status_parameter (osc$status_parameter_delimiter, field_value_info.project_name^,
                status);
          osp$append_status_parameter (osc$status_parameter_delimiter, field_value_info.account_name^,
                status);
        IFEND;
      IFEND;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_acct_proj_value;
?? TITLE := '    avp$change_accum_limit_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of an accumulating limit type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_accum_limit_value
    (    field_name: ost$name;
         job_warning_limit: ^avt$limit_value;
         job_maximum_limit: ^avt$limit_value;
         total_limit: ^avt$limit_value;
         total_accumulation: ^avt$limit_value;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change job warning if specified.

      IF job_warning_limit <> NIL THEN
        NEXT field_value_info.job_warning_limit IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.job_warning_limit^ := job_warning_limit^;
      IFEND;

{ Change job maximum limit if specified.

      IF job_maximum_limit <> NIL THEN
        NEXT field_value_info.job_maximum_limit IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.job_maximum_limit^ := job_maximum_limit^;
      IFEND;

{ Change total limit if specified.

      IF total_limit <> NIL THEN
        NEXT field_value_info.total_limit IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.total_limit^ := total_limit^;
      IFEND;

{ Change total accumulation if specified.

      IF total_accumulation <> NIL THEN
        NEXT field_value_info.total_accumulation IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.total_accumulation^ := total_accumulation^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_accum_limit_value;
?? TITLE := '    avp$change_capability_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a capability type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_capability_value
    (    field_name: ost$name;
         capability: ^boolean;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change capability value if specified.

      IF capability <> NIL THEN
        NEXT field_value_info.capability IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.capability^ := capability^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_capability_value;
?? TITLE := '    avp$change_date_time_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a date time type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_date_time_value
    (    field_name: ost$name;
         date_time: ^avt$date_time;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change date time value if specified.

      IF date_time <> NIL THEN
        NEXT field_value_info.date_time IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.date_time^ := date_time^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_date_time_value;
?? TITLE := '    avp$change_file_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a file type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_file_value
    (    field_name: ost$name;
         file: ^fst$file_reference;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change file value if specified.

      IF file <> NIL THEN
        NEXT field_value_info.file: [clp$trimmed_string_size (file^)] IN
              validation_record_info^.work_area.sequence_pointer;
        field_value_info.file^ := file^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_file_value;
?? TITLE := '    avp$change_integer_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of an integer type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_integer_value
    (    field_name: ost$name;
         integer_value: ^integer;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change integer value if specified.

      IF integer_value <> NIL THEN
        NEXT field_value_info.integer_value IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.integer_value^ := integer_value^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_integer_value;
?? TITLE := '    avp$change_job_class_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a job class type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_job_class_value
    (    field_name: ost$name;
         add_job_classes: ^avt$name_list;
         delete_job_classes: ^avt$name_list;
         batch_job_class_default: ^ost$name;
         interactive_job_class_default: ^ost$name;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      index: 1 .. avc$maximum_name_list_size,
      job_class_list: array [1 .. avc$maximum_name_list_size] of ost$name,
      number_of_job_classes: 1 .. avc$maximum_name_list_size,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Initialize a temporary array for holding the new list of job classes.

      FOR index := 1 TO avc$maximum_name_list_size DO
        job_class_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of job classes to the temporary array.

      FOR index := 1 TO UPPERBOUND (field_value_list_entry^.field_value.job_classes^) DO
        job_class_list [index] := field_value_list_entry^.field_value.job_classes^ [index];
      FOREND;
      number_of_job_classes := UPPERBOUND (field_value_list_entry^.field_value.job_classes^);

{ Delete any specified job classes from the temporary array.

      IF delete_job_classes <> NIL THEN
        delete_names_from_name_list (delete_job_classes, 'delete_job_classes', job_class_list,
              number_of_job_classes, status);
      IFEND;

{ Add any specified job classes to the temporary array.

      IF add_job_classes <> NIL THEN
        add_names_to_name_list (add_job_classes, 'add_job_classes', job_class_list, number_of_job_classes,
              status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Move the temporary array to the job classes field.

      NEXT field_value_info.job_classes: [1 .. number_of_job_classes] IN
            validation_record_info^.work_area.sequence_pointer;
      FOR index := 1 TO number_of_job_classes DO
        field_value_info.job_classes^ [index] := job_class_list [index];
      FOREND;

{ Change the batch job class default value if specified.

      IF batch_job_class_default <> NIL THEN
        NEXT field_value_info.batch_job_class_default IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.batch_job_class_default^ := batch_job_class_default^;
      IFEND;

{ Change the interactive job class default value if specified.

      IF interactive_job_class_default <> NIL THEN
        NEXT field_value_info.interactive_job_class_default IN
              validation_record_info^.work_area.sequence_pointer;
        field_value_info.interactive_job_class_default^ := interactive_job_class_default^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_job_class_value;
?? TITLE := '    avp$change_labeled_names_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a name type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_labeled_names_value
    (    field_name: ost$name;
         add_labeled_names: ^avt$labeled_names_list;
         delete_labeled_names: ^avt$labeled_names_list;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      field_work_area: ^seq (*),
      index: 1 .. avc$maximum_name_list_size,
      labeled_names: ^avt$labeled_names_list,
      name_list: array [1 .. avc$maximum_name_list_size] of ost$name,
      number_of_names: 1 .. avc$maximum_name_list_size,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      find_validation_record_info (record_id, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      NEXT field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]] IN
            validation_record_info^.work_area.sequence_pointer;
      RESET field_work_area;

      initialize_change_value_info (field_name, record_id, field_work_area, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

  { Change the labeled names field value.

      change_labeled_names (add_labeled_names, delete_labeled_names, field_value_info,
            validation_record_info^.work_area.sequence_pointer, labeled_names, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

  { Move the temporary labeled names array to the labeled names field.

      NEXT field_value_info.labeled_names: [1 .. UPPERBOUND (labeled_names^)] IN
            validation_record_info^.work_area.sequence_pointer;
      FOR index := 1 TO UPPERBOUND (labeled_names^) DO
        field_value_info.labeled_names^ [index] := labeled_names^ [index];
      FOREND;

  { Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_labeled_names_value;
?? TITLE := '    avp$change_limit_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a limit type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_limit_value
    (    field_name: ost$name;
         limit_value: ^avt$limit_value;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change limit value if specified.

      IF limit_value <> NIL THEN
        NEXT field_value_info.limit_value IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.limit_value^ := limit_value^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_limit_value;
?? TITLE := '    avp$change_login_password_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a login password type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The maximum expiration interval and password attributes fields are
{ changeable only by user administrators or above even if the change
{ authority for the field is below user administrator.
{
{   Specifying an expiration date without specifying a new password may only be
{ done by user administrators or above even if the change authority for the
{ field is below user administrator.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{
{   If update_batch_job_passwords = TRUE, then update the login_password in queued
{ and deferred batch jobs belonging to the user to the new value.

  PROCEDURE [XDCL, #GATE] avp$change_login_password_value
    (    field_name: ost$name;
         old_password: ^string (osc$max_name_size);
         login_password: ^avt$login_password;
         login_password_exp_date: ^ost$date_time;
         login_password_exp_interval: ^pmt$time_increment;
         login_password_max_exp_interval: ^pmt$time_increment;
         login_password_exp_warning: ^pmt$time_increment;
         login_password_exp_chg_interval: ^pmt$time_increment;
         add_password_attributes: ^avt$name_list;
         delete_password_attributes: ^avt$name_list;
         record_id: ost$name;
         update_batch_job_passwords: boolean;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      current_date_time: ost$date_time,
      evaluated_file_reference: fst$evaluated_file_reference,
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      file_utility_information: ^avt$file_utility_information,
      index: 1 .. avc$maximum_name_list_size,
      input_attribute_changes_p: ^jmt$input_attribute_changes,
      job_index: jmt$job_status_count,
      job_name: jmt$name,
      job_status_options_p: ^jmt$job_status_options,
      job_status_results_keys_p: ^jmt$results_keys,
      job_status_results_p: ^jmt$job_status_results,
      login_password_attribute_list: array [1 .. avc$maximum_name_list_size] of ost$name,
      new_password: string (osc$max_name_size),
      number_of_jobs_found: jmt$job_status_count,
      number_of_password_attributes: 1 .. avc$maximum_name_list_size,
      old_login_password: avt$login_password,
      result_size: ost$segment_length,
      type_specification: avt$type_specification,
      user_name: ost$user_name,
      utility_information: ^avt$utility_information,
      validation_record_info: ^avt$validation_record_info,
      verified_old_password: string (osc$max_name_size),
      verified_old_login_password: avt$login_password,
      work_area_p: ^jmt$work_area;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

{ Get the current date and time.

      pmp$get_compact_date_time (current_date_time, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      old_login_password := field_value_list_entry^.field_value.login_password^;
      field_value_info := field_value_list_entry^.field_value;

{ Unconditional allocation of all of the fields is done up front in this procedure because
{ the password attribute change hook may assign new values which must be stored in the work area heap.

      NEXT field_value_info.login_password IN validation_record_info^.work_area.sequence_pointer;
      field_value_info.login_password^ := field_value_list_entry^.field_value.login_password^;

      NEXT field_value_info.login_password_exp_date IN validation_record_info^.work_area.sequence_pointer;
      field_value_info.login_password_exp_date^ :=
            field_value_list_entry^.field_value.login_password_exp_date^;

      NEXT field_value_info.login_password_exp_interval IN validation_record_info^.work_area.sequence_pointer;
      field_value_info.login_password_exp_interval^ := field_value_list_entry^.field_value.
            login_password_exp_interval^;

      NEXT field_value_info.login_password_exp_warning IN validation_record_info^.work_area.sequence_pointer;
      field_value_info.login_password_exp_warning^ := field_value_list_entry^.field_value.
            login_password_exp_warning^;

      NEXT field_value_info.login_password_exp_chg_interval IN
            validation_record_info^.work_area.sequence_pointer;
      field_value_info.login_password_exp_chg_interval^ := field_value_list_entry^.field_value.
            login_password_exp_chg_interval^;

      NEXT field_value_info.login_password_change_date IN
            validation_record_info^.work_area.sequence_pointer;
      IF field_value_list_entry^.field_value.login_password_change_date = NIL THEN
          field_value_info.login_password_change_date^.year :=
                LOWERVALUE (field_value_info.login_password_change_date^.year);
          field_value_info.login_password_change_date^.month :=
                LOWERVALUE (field_value_info.login_password_change_date^.month);
          field_value_info.login_password_change_date^.day :=
                LOWERVALUE (field_value_info.login_password_change_date^.day);
          field_value_info.login_password_change_date^.hour :=
                LOWERVALUE (field_value_info.login_password_change_date^.hour);
          field_value_info.login_password_change_date^.minute :=
                LOWERVALUE (field_value_info.login_password_change_date^.minute);
          field_value_info.login_password_change_date^.second :=
                LOWERVALUE (field_value_info.login_password_change_date^.second);
          field_value_info.login_password_change_date^.millisecond :=
                LOWERVALUE (field_value_info.login_password_change_date^.millisecond);
      ELSE
        field_value_info.login_password_change_date^ := field_value_list_entry^.field_value.
              login_password_change_date^;
      IFEND;

      NEXT field_value_info.login_password_max_exp_interval IN
            validation_record_info^.work_area.sequence_pointer;
      field_value_info.login_password_max_exp_interval^ := field_value_list_entry^.field_value.
            login_password_max_exp_interval^;

{ Change the maximum expiration interval if specified.
{ The caller must have user administration authority or above to change this value.

      IF login_password_max_exp_interval <> NIL THEN
        IF validation_record_info^.caller_authority < avc$user_admin_authority THEN
          osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          EXIT /change/;
        IFEND;
        field_value_info.login_password_max_exp_interval^ := login_password_max_exp_interval^;
      IFEND;

{ Change the expiration date if specified.
{ Only user administrators or above may specify an expiration date
{ without specifying a new password.

      IF login_password_exp_date <> NIL THEN
        IF ((login_password = NIL) AND (validation_record_info^.caller_authority < avc$user_admin_authority))
              THEN
          osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          EXIT /change/;
        IFEND;
        field_value_info.login_password_exp_date^ := login_password_exp_date^;
      IFEND;

{ Change the expiration interval value if specified.

      IF login_password_exp_interval <> NIL THEN
        field_value_info.login_password_exp_interval^ := login_password_exp_interval^;
      IFEND;

{ Change the expiration warning interval if specified.

      IF login_password_exp_warning <> NIL THEN
        field_value_info.login_password_exp_warning^ := login_password_exp_warning^;
      IFEND;

{ Change the expired password change interval if specified.

      IF login_password_exp_chg_interval <> NIL THEN
        field_value_info.login_password_exp_chg_interval^ := login_password_exp_chg_interval^;
      IFEND;

{ Initialize a temporary array for holding the new list of password attributes.

      FOR index := 1 TO avc$maximum_name_list_size DO
        login_password_attribute_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of password attributes to the temporary array.

      FOR index := 1 TO UPPERBOUND (field_value_list_entry^.field_value.login_password_attributes^) DO
        login_password_attribute_list [index] := field_value_list_entry^.field_value.
              login_password_attributes^ [index];
      FOREND;
      number_of_password_attributes := UPPERBOUND (field_value_list_entry^.field_value.
            login_password_attributes^);

{ Delete any specified password attributes from the temporary array.

      IF delete_password_attributes <> NIL THEN
        IF validation_record_info^.caller_authority < avc$user_admin_authority THEN
          osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          EXIT /change/;
        ELSE
          delete_names_from_name_list (delete_password_attributes, 'delete_password_attributes',
                login_password_attribute_list, number_of_password_attributes, status);
          IF NOT status.normal THEN
            EXIT /change/;
          IFEND;
        IFEND;
      IFEND;

{ Add any specified password attributes to the temporary array.

      IF add_password_attributes <> NIL THEN
        IF validation_record_info^.caller_authority < avc$user_admin_authority THEN
          osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          EXIT /change/;
        ELSE
          add_names_to_name_list (add_password_attributes, 'add_password_attributes',
                login_password_attribute_list, number_of_password_attributes, status);
          IF NOT status.normal THEN
            EXIT /change/;
          IFEND;
        IFEND;
      IFEND;

      field_value_info.login_password_attributes := ^login_password_attribute_list;

{ Change the login password value if specified.

      IF login_password <> NIL THEN
        IF old_password = NIL THEN

{ Only user administrators or above may specify a new password without specifying the old.

          IF ((validation_record_info^.caller_authority < avc$user_admin_authority) AND
                (NOT login_password^.encrypted)) THEN
            osp$set_status_abnormal ('AV', ave$old_password_not_valid, 'user', status);
            EXIT /change/;
          IFEND;
          verified_old_password := osc$null_name;
        ELSE

{ Encrypt the old password value.

          verified_old_login_password.encrypted := TRUE;
          avp$encrypt_password (validation_record_info^.key.user_name, old_password^,
                verified_old_login_password.value, status);
          IF NOT status.normal THEN
            EXIT /change/;
          IFEND;

{ Verify that the correct old password value was specified.

          IF verified_old_login_password.value <> old_login_password.value THEN
            avp$old_encrypt_password (validation_record_info^.key.user_name, old_password^,
                verified_old_login_password.value, status);
            IF NOT status.normal THEN
              EXIT /change/;
            IFEND;
            IF verified_old_login_password.value <> old_login_password.value THEN
              osp$set_status_abnormal ('AV', ave$old_password_not_valid, 'user', status);
              EXIT /change/;
            IFEND;
          IFEND;
          verified_old_login_password.value := osc$null_name;
          verified_old_password := old_password^;
        IFEND;

{ Calculate a new expiration date if one wasn't specified.

        IF login_password_exp_date = NIL THEN
          IF field_value_info.login_password_exp_interval^.day <> avc$unlimited_exp_interval THEN
            pmp$compute_date_time (current_date_time, field_value_info.login_password_exp_interval^,
                  field_value_info.login_password_exp_date^, status);
            IF NOT status.normal THEN
              IF ((status.condition = pme$compute_overflow) OR (status.condition =
                    pme$computed_year_out_of_range)) THEN
                field_value_info.login_password_exp_date^.year := avc$no_expiration_date;
                status.normal := TRUE;
              ELSE
                EXIT /change/;
              IFEND;
            IFEND;
          ELSE
            field_value_info.login_password_exp_date^.year := avc$no_expiration_date;
          IFEND;
        IFEND;

{ Encrypted passwords are allowed only if this is a new validation file.
{ This is to facilitate recreation from source.

        IF login_password^.encrypted THEN
          PUSH utility_information: [[REP 1 OF avt$file_utility_information]];
          RESET utility_information;
          avp$get_file_utility_info (utility_information, file_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          RESET utility_information;
          NEXT file_utility_information IN utility_information;
          IF file_utility_information = NIL THEN
            corrupted_sequence ('AVP$CHANGE_LOGIN_PASSWORD_VALUE', 'NEW_FILE', 'FILE_UTILITY_INFORMATION',
                  status);
            EXIT /change/;
          IFEND;
          IF NOT file_utility_information^.new_file THEN
            osp$set_status_abnormal ('AV', ave$encrypted_pw_not_allowed, '', status);
            EXIT /change/;
          IFEND;
          field_value_info.login_password^ := login_password^;
        ELSE

{ Encrypt the new password.

          field_value_info.login_password^.encrypted := TRUE;
          avp$encrypt_password (validation_record_info^.key.user_name, login_password^.value,
                field_value_info.login_password^.value, status);
          IF NOT status.normal THEN
            EXIT /change/;
          IFEND;
          new_password := login_password^.value;

{ Call the password attribute site hook.

          avp$process_password_attributes (validation_record_info^.caller_authority,
                validation_record_info^.key.user_name,
                field_value_info.login_password_change_date^, old_login_password,
                field_value_info.login_password^, verified_old_password, new_password,
                field_value_info.login_password_attributes^, number_of_password_attributes, status);
          IF NOT status.normal THEN
            EXIT /change/;
          IFEND;

{ The site hook must not return a blank new password.

          IF new_password = osc$null_name THEN
            osp$set_status_abnormal ('AV', ave$invalid_password_from_hook, '', status);
            EXIT /change/;
          IFEND;
          field_value_info.login_password^.encrypted := TRUE;

{ Encrypt the new password returned by the site hook.

          avp$encrypt_password (validation_record_info^.key.user_name, new_password,
                field_value_info.login_password^.value, status);
          IF NOT status.normal THEN
            EXIT /change/;
          IFEND;
          new_password := osc$null_name;
        IFEND;

        field_value_info.login_password_change_date^ := current_date_time;

      IFEND;

{ Move the temporary array to the password attributes field.

      NEXT field_value_info.login_password_attributes: [1 .. number_of_password_attributes] IN
            validation_record_info^.work_area.sequence_pointer;
      FOR index := 1 TO number_of_password_attributes DO
        field_value_info.login_password_attributes^ [index] := login_password_attribute_list [index];
      FOREND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Update passwords in queued and deferred jobs, if caller requested it.

  /update_jobs/
    BEGIN
      IF status.normal AND update_batch_job_passwords THEN

{ Get the family name.

        clp$evaluate_file_reference (file_information.file_name, $clt$file_ref_parsing_options [],
              FALSE, evaluated_file_reference, status);
        IF NOT status.normal THEN
          EXIT /update_jobs/;
        IFEND;

{ Find the user's jobs.

        PUSH job_status_options_p: [1 .. 4];
        job_status_options_p^ [1].key := jmc$login_family;
        job_status_options_p^ [1].login_family := fsp$path_element (^evaluated_file_reference, 1)^;
        job_status_options_p^ [2].key := jmc$login_user;
        job_status_options_p^ [2].login_user := validation_record_info^.key.user_name;
        job_status_options_p^ [3].key := jmc$job_state_set;
        job_status_options_p^ [3].job_state_set := $jmt$job_state_set [jmc$deferred_job, jmc$queued_job,
              jmc$completed_job];
        job_status_options_p^ [4].key := jmc$continue_request_to_servers;
        job_status_options_p^ [4].continue_request_to_servers := TRUE;

        PUSH job_status_results_keys_p: [1 .. 1];
        job_status_results_keys_p^ [1] := jmc$system_job_name;

{ Guess how many jobs might be found.  If the number is too few, it will be incremented below.

        jmp$get_result_size ( { number_of_items } 5, #SEQ (job_status_results_keys_p^), result_size);
        PUSH work_area_p: [[REP result_size OF cell]];
        RESET work_area_p;
        jmp$get_job_status (job_status_options_p, job_status_results_keys_p, work_area_p,
              job_status_results_p, number_of_jobs_found, status);

        WHILE (NOT status.normal) AND (status.condition = jme$work_area_too_small) DO
          status.normal := TRUE;
          jmp$get_result_size (number_of_jobs_found + 1, #SEQ (job_status_results_keys_p^), result_size);
          PUSH work_area_p: [[REP result_size OF cell]];
          RESET work_area_p;
          jmp$get_job_status (job_status_options_p, job_status_results_keys_p, work_area_p,
                job_status_results_p, number_of_jobs_found, status);
        WHILEND;

        IF NOT status.normal THEN
          IF status.condition = jme$no_jobs_were_found THEN
            status.normal := TRUE;
          IFEND;
          EXIT /update_jobs/;
        IFEND;


{ Change the login password for the jobs that were found.

        PUSH input_attribute_changes_p: [1 .. 1];
        input_attribute_changes_p^ [1].key := jmc$encrypted_password;
        input_attribute_changes_p^ [1].encrypted_password := field_value_info.login_password^.value;
        job_name.kind := jmc$system_supplied_name;

        FOR job_index := 1 TO number_of_jobs_found DO
          job_name.system_supplied_name := job_status_results_p^ [job_index]^ [1].system_job_name;
          jmp$change_input_attributes (job_name, input_attribute_changes_p, status);
          IF NOT status.normal THEN
            IF (status.condition = jme$input_is_initiated) OR (status.condition = jme$name_not_found) THEN
              status.normal := TRUE;
            ELSE
              EXIT /update_jobs/;
            IFEND;
          IFEND;
        FOREND;
      IFEND;
    END /update_jobs/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_login_password_value;
?? TITLE := '    avp$change_name_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a name type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_name_value
    (    field_name: ost$name;
         add_names: ^avt$name_list;
         delete_names: ^avt$name_list;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      index: 1 .. avc$maximum_name_list_size,
      name_list: array [1 .. avc$maximum_name_list_size] of ost$name,
      number_of_names: 1 .. avc$maximum_name_list_size,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Initialize a temporary array for holding the new list of names.

      FOR index := 1 TO avc$maximum_name_list_size DO
        name_list [index] := osc$null_name;
      FOREND;

{ Copy the current list of names to the temporary array.

      FOR index := 1 TO UPPERBOUND (field_value_list_entry^.field_value.names^) DO
        name_list [index] := field_value_list_entry^.field_value.names^ [index];
      FOREND;
      number_of_names := UPPERBOUND (field_value_list_entry^.field_value.names^);

{ Delete any specified names from the temporary array.

      IF delete_names <> NIL THEN
        delete_names_from_name_list (delete_names, 'delete_names', name_list, number_of_names, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Add any specified names to the temporary array.

      IF add_names <> NIL THEN
        add_names_to_name_list (add_names, 'add_names', name_list, number_of_names, status);
        IF NOT status.normal THEN
          EXIT /change/;
        IFEND;
      IFEND;

{ Move the temporary array to the name field.

      NEXT field_value_info.names: [1 .. number_of_names] IN
            validation_record_info^.work_area.sequence_pointer;
      FOR index := 1 TO number_of_names DO
        field_value_info.names^ [index] := name_list [index];
      FOREND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_name_value;
?? TITLE := '    avp$change_real_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a real type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_real_value
    (    field_name: ost$name;
         real_value: ^real;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change the real value if specified.

      IF real_value <> NIL THEN
        NEXT field_value_info.real_value IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.real_value^ := real_value^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_real_value;
?? TITLE := '    avp$change_ring_privilege_value', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a ring privilege type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_ring_privilege_value
    (    field_name: ost$name;
         minimum_ring: ^ost$ring;
         nominal_ring: ^ost$ring;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change minimum ring value if specified.

      IF minimum_ring <> NIL THEN
        NEXT field_value_info.minimum_ring IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.minimum_ring^ := minimum_ring^;
      IFEND;

{ Change nominal ring value if specified.

      IF nominal_ring <> NIL THEN
        NEXT field_value_info.nominal_ring IN validation_record_info^.work_area.sequence_pointer;
        field_value_info.nominal_ring^ := nominal_ring^;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_ring_privilege_value;
?? TITLE := '    avp$change_string_value', EJECT ??
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to change the value of a string type
{ validation field within a validation record that has been previously
{ stored by a separate validation interface.
{
{ DESIGN:
{
{   This interface first calls a local procedure which, verifies that the
{ caller has the required authority to change the field requested, gets
{ pointers to the requested validation record information in memory, and
{ retrieves the current value for the field being changed.
{
{   The current values for the field being changed are replaced by any values
{ specified on the input parameters, and the resulting field value is
{ verified for type conformance.
{

  PROCEDURE [XDCL, #GATE] avp$change_string_value
    (    field_name: ost$name;
         string_value: ^ost$string;
         record_id: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_value_info: avt$field_value,
      field_value_list_entry: ^avt$field_value_list_entry,
      validation_record_info: ^avt$validation_record_info,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Set up for changing a field value.

  /change/
    BEGIN
      initialize_change_value_info (field_name, record_id, {work_area=} NIL, type_specification,
            field_value_list_entry, validation_record_info, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_info := field_value_list_entry^.field_value;

{ Change the string value if specified.

      IF string_value <> NIL THEN
        NEXT field_value_info.string_value: [string_value^.size] IN
              validation_record_info^.work_area.sequence_pointer;
        field_value_info.string_value^ := string_value^.value;
      IFEND;

{ Verify values are valid for this type.

      avp$verify_type_conformance (field_name, field_value_info, type_specification, status);
      IF NOT status.normal THEN
        EXIT /change/;
      IFEND;

      field_value_list_entry^.field_value := field_value_info;
    END /change/;

{ Emit the audit statistic for unsuccessful changes (successful changes are audited when the subutility ends).

    IF (avp$security_option_active (avc$vso_security_audit)) AND (NOT status.normal) THEN
      emit_chg_value_audit_statistic (validation_record_info^.description_record_name,
            file_information.file_name, validation_record_info^.key, field_name, status);
    IFEND;

  PROCEND avp$change_string_value;
?? OLDTITLE ??
?? TITLE := '  Interfaces to read field display values' ??
?? NEWTITLE := '    avp$get_acct_proj_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get an account project type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_acct_proj_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR account_name: avt$account_name;
     VAR project_name: avt$project_name;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$account_project_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'account project', status);
      RETURN;
    IFEND;

{ Return the current field values.

    account_name := field_value.account_name^;
    project_name := field_value.project_name^;

  PROCEND avp$get_acct_proj_display_value;
?? TITLE := '    avp$get_accum_limit_display_val', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a accum limit type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_accum_limit_display_val
    (    field_name: ost$name;
         record_id: ost$name;
     VAR job_limit_information: avt$job_limit_information;
     VAR total_limit_information: avt$total_limit_information;
     VAR display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$accumulating_limit_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'accumulating limit', status);
      RETURN;
    IFEND;

{ Return the job limit information if job limits apply.

    job_limit_information.job_limits_apply := type_specification.job_limits_apply^;
    IF job_limit_information.job_limits_apply THEN
      job_limit_information.job_warning_limit := field_value.job_warning_limit^;
      job_limit_information.job_maximum_limit := field_value.job_maximum_limit^;
    IFEND;

{ Return total limit information if total limits apply.

    total_limit_information.total_limit_applies := type_specification.total_limit_applies^;
    IF total_limit_information.total_limit_applies THEN
      total_limit_information.total_limit := field_value.total_limit^;
      total_limit_information.total_accumulation := field_value.total_accumulation^;
    IFEND;

{ The following code is temporary.  It will be replaced when limit display
{ formats are taken from the type specifiation (in a future release).

    display_format.field_size := 10;
    display_format.kind := avc$integer_format;
    display_format.radix := 10;
    display_format.display_radix := FALSE;

  PROCEND avp$get_accum_limit_display_val;
?? TITLE := '    avp$get_capabil_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a capability type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_capabil_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR capability: boolean;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$capability_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'capability', status);
      RETURN;
    IFEND;

{ Return the current field values.

    capability := field_value.capability^;

  PROCEND avp$get_capabil_display_value;
?? TITLE := '    avp$get_date_time_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a date time type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_date_time_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR date_time: avt$date_time;
     VAR date_display_format: clt$date_time_form_string;
     VAR time_display_format: clt$date_time_form_string;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$date_time_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'date time', status);
      RETURN;
    IFEND;

{ Return the current field values.

    date_time := field_value.date_time^;

{ Return the date display format if dates apply.

    IF type_specification.date_applies^ THEN
      date_display_format := type_specification.date_display_format^;
    ELSE
      date_display_format := ' ';
    IFEND;

{ Return the time display format if times apply.

    IF type_specification.time_applies^ THEN
      time_display_format := type_specification.time_display_format^;
    ELSE
      time_display_format := ' ';
    IFEND;

  PROCEND avp$get_date_time_display_value;
?? TITLE := '    avp$get_file_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a file type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_file_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR file: string (fsc$max_path_size);
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$file_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'file', status);
      RETURN;
    IFEND;

{ Return the current field value.

    file := field_value.file^;

  PROCEND avp$get_file_display_value;
?? TITLE := '    avp$get_integer_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get an integer type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_integer_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR integer_value: integer;
     VAR display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$integer_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'integer', status);
      RETURN;
    IFEND;

{ Return the current field value.

    integer_value := field_value.integer_value^;

{ Return the display format.

    display_format := type_specification.integer_display_format^;

  PROCEND avp$get_integer_display_value;
?? TITLE := '    avp$get_job_class_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a job class type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_job_class_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR job_classes: avt$name_list;
     VAR number_of_job_classes: avt$name_list_size;
     VAR batch_job_class_default: ost$name;
     VAR interactive_job_class_default: ost$name;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$job_class_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'job class', status);
      RETURN;
    IFEND;

{ Return as many of the job class validation values as will fit.

    FOR index := 1 TO UPPERBOUND (job_classes) DO
      IF index <= UPPERBOUND (field_value.job_classes^) THEN
        job_classes [index] := field_value.job_classes^ [index];
      ELSE
        job_classes [index] := osc$null_name;
      IFEND;
    FOREND;

{ Return the actual number of job classes.

    number_of_job_classes := UPPERBOUND (field_value.job_classes^);

{ Return the batch and interactive job class defaults.

    batch_job_class_default := field_value.batch_job_class_default^;
    interactive_job_class_default := field_value.interactive_job_class_default^;

  PROCEND avp$get_job_class_display_value;
?? TITLE := '    avp$get_labeled_names_dis_value', EJECT ??
{ PURPOSE:
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a labeled names type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_labeled_names_dis_value
    (    field_name: ost$name;
         record_id: ost$name;
         work_area: ^seq (*);
     VAR labeled_names:  ^avt$labeled_names_list;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      field_work_area: ^seq (*),
      index: avt$name_list_size,
      type_specification: avt$type_specification,
      work_area_ptr: ^seq (*);

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
    RESET field_work_area;
    init_get_display_value_info (field_name, record_id, field_work_area, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$labeled_names_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'labeled name', status);
      RETURN;
    IFEND;

{ Return the labeled names field value.

    IF field_value.labeled_names <> NIL THEN
      work_area_ptr := work_area;
      NEXT labeled_names: [1 .. UPPERBOUND (field_value.labeled_names^)] IN work_area_ptr;
      FOR index := 1 TO UPPERBOUND (field_value.labeled_names^) DO
        NEXT labeled_names^ [index].label IN work_area_ptr;
        labeled_names^ [index].label^ := field_value.labeled_names^ [index].label^;

        NEXT labeled_names^ [index].names: [1 .. UPPERBOUND (field_value.labeled_names^ [index].names^)] IN
              work_area_ptr;
        labeled_names^ [index].names^ := field_value.labeled_names^ [index].names^;
      FOREND;
    ELSE
      labeled_names := NIL;
    IFEND;

  PROCEND avp$get_labeled_names_dis_value;
?? TITLE := '    avp$get_limit_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a limit type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_limit_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR limit_value: avt$limit_value;
     VAR display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$limit_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'limit', status);
      RETURN;
    IFEND;

{ Return the value of the validation field.

    limit_value := field_value.limit_value^;

{ The following code is temporary.  It will be replaced when limit display
{ formats are taken from the type specifiation (in a future release).

    display_format.field_size := 10;
    display_format.kind := avc$integer_format;
    display_format.radix := 10;
    display_format.display_radix := FALSE;

  PROCEND avp$get_limit_display_value;
?? TITLE := '    avp$get_login_pw_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a login password type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_login_pw_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR expiration_date: ost$date_time;
     VAR expiration_interval: pmt$time_increment;
     VAR maximum_expiration_interval: pmt$time_increment;
     VAR expiration_warning_interval: pmt$time_increment;
     VAR expired_password_chg_interval: pmt$time_increment;
     VAR change_date: ost$date_time;
     VAR attributes: avt$name_list;
     VAR number_of_attributes: avt$name_list_size;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$login_password_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'login password', status);
      RETURN;
    IFEND;

{ Return the values for the validation field.  The encrypted password value is
{ not returned for security reasons.

    expiration_date := field_value.login_password_exp_date^;
    expiration_interval := field_value.login_password_exp_interval^;
    maximum_expiration_interval := field_value.login_password_max_exp_interval^;
    expiration_warning_interval := field_value.login_password_exp_warning^;
    expired_password_chg_interval := field_value.login_password_exp_chg_interval^;
    IF field_value.login_password_change_date = NIL THEN
      change_date.year := LOWERVALUE (change_date.year);
      change_date.month := LOWERVALUE (change_date.month);
      change_date.day := LOWERVALUE (change_date.day);
      change_date.hour := LOWERVALUE (change_date.hour);
      change_date.minute := LOWERVALUE (change_date.minute);
      change_date.second := LOWERVALUE (change_date.second);
      change_date.millisecond := LOWERVALUE (change_date.millisecond);
    ELSE
      change_date := field_value.login_password_change_date^;
    IFEND;

{ Return as many password attributes as will fit.

    FOR index := 1 TO UPPERBOUND (attributes) DO
      IF index <= UPPERBOUND (field_value.login_password_attributes^) THEN
        attributes [index] := field_value.login_password_attributes^ [index];
      ELSE
        attributes [index] := osc$null_name;
      IFEND;
    FOREND;

{ Return the actual number of password attributes.

    number_of_attributes := UPPERBOUND (field_value.login_password_attributes^);

  PROCEND avp$get_login_pw_display_value;
?? TITLE := '    avp$get_name_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a name type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_name_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR names: avt$name_list;
     VAR number_of_names: avt$name_list_size;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$name_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'name', status);
      RETURN;
    IFEND;

{ Return as many names as will fit.

    FOR index := 1 TO UPPERBOUND (names) DO
      IF index <= UPPERBOUND (field_value.names^) THEN
        names [index] := field_value.names^ [index];
      ELSE
        names [index] := osc$null_name;
      IFEND;
    FOREND;

{ Return the actual number of names.

    number_of_names := UPPERBOUND (field_value.names^);

  PROCEND avp$get_name_display_value;
?? TITLE := '    avp$get_real_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a real type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_real_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR real_value: real;
     VAR display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$real_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'real', status);
      RETURN;
    IFEND;

{ Return the current field values.

    real_value := field_value.real_value^;

{ Return the display format.

    display_format := type_specification.real_display_format^;

  PROCEND avp$get_real_display_value;
?? TITLE := '    avp$get_ring_priv_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a ring privilege type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_ring_priv_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR minimum_ring: ost$ring;
     VAR nominal_ring: ost$ring;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$ring_privilege_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'ring privilege', status);
      RETURN;
    IFEND;

{ Return the current field values.

    minimum_ring := field_value.minimum_ring^;
    nominal_ring := field_value.nominal_ring^;

  PROCEND avp$get_ring_priv_display_value;
?? TITLE := '    avp$get_string_display_value', EJECT ??
{
{ PURPOSE:
{
{   This interface is an internal interface for use by the AV project only.
{
{   This interface is used to get a string type field's current values
{ from the validation record information currently stored for a subutility session.
{
{ DESIGN:
{
{   This interface calls a local procedure which:
{     - Verifies that the caller has authority to display the value.
{     - Finds the current field value in the validation record information chain.
{   Then the field values are returned to the caller.
{

  PROCEDURE [XDCL, #GATE] avp$get_string_display_value
    (    field_name: ost$name;
         record_id: ost$name;
     VAR string_value: ost$string;
     VAR status: ost$status);

    VAR
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ Validate the caller and get the field value to display.

    init_get_display_value_info (field_name, record_id, {work_area=} NIL, field_value, type_specification,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$string_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'string', status);
      RETURN;
    IFEND;

{ Return the current field values.

    IF field_value.string_value = NIL THEN
      string_value.value := ' ';
      string_value.size := 0;
    ELSE
      string_value.value := field_value.string_value^;
      string_value.size := #SIZE (field_value.string_value^);
    IFEND;

  PROCEND avp$get_string_display_value;
?? OLDTITLE ??
?? TITLE := '  Interfaces to read field values for the currently executing job' ??
?? NEWTITLE := '    avp$get_field_type', EJECT ??

{ PURPOSE:
{
{   This interface is used to return the field kind of a specified validation
{ field name.
{
{ DESIGN:
{
{   The field kind is retrieved from the type specification within the description
{ record.
{

  PROCEDURE [XDCL, #GATE] avp$get_field_type
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR field_kind: avt$field_kind;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      data_record: ^avt$template_file_record,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      descriptive_text: ^avt$descriptive_text,
      field_work_area: ^seq (*),
      type_specification: avt$type_specification,
      utility_information: ^avt$utility_information;

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

{ Get pointers to the specified job validation records.

    get_job_validation_record (caller_id, record_level, caller_authority, data_record, description_record,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Retrieve the field description for the specified field from the description record.

    PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
    RESET field_work_area;
    avp$get_field_description (field_name, description_record, field_work_area, type_specification,
          default_value, descriptive_text, utility_information, status);
    IF status.normal OR (status.condition = ave$field_was_deleted) THEN
      field_kind := type_specification.kind;
    IFEND;

  PROCEND avp$get_field_type;
?? OLDTITLE ??
?? NEWTITLE := '    avp$get_account_project_value', EJECT ??

*copyc avh$get_account_project_value

  PROCEDURE [XDCL, #GATE] avp$get_account_project_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR account: avt$account_name;
     VAR project: avt$project_name;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$account_project_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'account project', status);
      RETURN;
    IFEND;

{ Return the value of the validation field.

    account := field_value.account_name^;
    project := field_value.project_name^;

  PROCEND avp$get_account_project_value;
?? TITLE := '    avp$get_accum_limit_value', EJECT ??
*copyc avh$get_accum_limit_value

  PROCEDURE [XDCL, #GATE] avp$get_accum_limit_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR job_limit_information: avt$job_limit_information;
     VAR total_limit_information: avt$total_limit_information;
     VAR display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$accumulating_limit_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'accumulating limit', status);
      RETURN;
    IFEND;

{ Return the job limit information if job limits apply.

    job_limit_information.job_limits_apply := type_specification.job_limits_apply^;
    IF job_limit_information.job_limits_apply THEN
      job_limit_information.job_warning_limit := field_value.job_warning_limit^;
      job_limit_information.job_maximum_limit := field_value.job_maximum_limit^;
    IFEND;

{ Return total limit information if total limits apply.

    total_limit_information.total_limit_applies := type_specification.total_limit_applies^;
    IF total_limit_information.total_limit_applies THEN
      total_limit_information.total_limit := field_value.total_limit^;
      total_limit_information.total_accumulation := field_value.total_accumulation^;
    IFEND;

{ The following code is temporary.  It will be replaced when limit display
{ formats are taken from the type specifiation (in a future release).

    display_format.field_size := 10;
    display_format.kind := avc$integer_format;
    display_format.radix := 10;
    display_format.display_radix := FALSE;

  PROCEND avp$get_accum_limit_value;
?? TITLE := '    avp$get_capability', EJECT ??
*copyc avh$get_capability

  PROCEDURE [XDCL, #GATE] avp$get_capability
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR capability: boolean;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

    capability := FALSE;

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$capability_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'capability', status);
      RETURN;
    IFEND;

{ Return the value of the validation field.

    capability := field_value.capability^;

  PROCEND avp$get_capability;
?? TITLE := '    avp$get_date_time_value', EJECT ??
*copyc avh$get_date_time_value

  PROCEDURE [XDCL, #GATE] avp$get_date_time_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR date_time: avt$date_time;
     VAR date_display_format: clt$date_time_form_string;
     VAR time_display_format: clt$date_time_form_string;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also verify that the caller has
{ sufficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$date_time_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'date time', status);
      RETURN;
    IFEND;

{ Return the value of the validation field.

    date_time := field_value.date_time^;

{ Return the date display format if dates apply.

    IF type_specification.date_applies^ THEN
      date_display_format := type_specification.date_display_format^;
    ELSE
      date_display_format := ' ';
    IFEND;

{ Return the time display format if times apply.

    IF type_specification.time_applies^ THEN
      time_display_format := type_specification.time_display_format^;
    ELSE
      time_display_format := ' ';
    IFEND;

  PROCEND avp$get_date_time_value;
?? TITLE := '    avp$get_field_name_list', EJECT ??
*copy avh$get_field_name_list

  PROCEDURE [XDCL, #GATE] avp$get_field_name_list
    (    record_level: avt$validation_record;
         desired_field_kinds: avt$field_kind_set;
     VAR field_names: avt$name_list;
     VAR field_count: avt$field_count;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      caller_id: ost$caller_identifier,
      data_record: ^avt$template_file_record,
      description_record: ^avt$template_file_record;

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

{ Get pointers to the specified validation information.

    get_job_validation_record (caller_id, record_level, caller_authority, data_record, description_record,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Extract the desired field names from the validation record.

    avp$get_field_names (desired_field_kinds, {deleted_fields =} FALSE, description_record, field_names,
          field_count, status);

  PROCEND avp$get_field_name_list;
?? TITLE := '    avp$get_file_value', EJECT ??
*copyc avh$get_file_value

  PROCEDURE [XDCL, #GATE] avp$get_file_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR file: string (fsc$max_path_size);
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$file_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'file', status);
      RETURN;
    IFEND;

{ Return value of the validation field.

    file := field_value.file^;

  PROCEND avp$get_file_value;
?? TITLE := '    avp$get_integer_value', EJECT ??
*copyc avh$get_integer_value

  PROCEDURE [XDCL, #GATE] avp$get_integer_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR integer_value: integer;
     VAR integer_display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$integer_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'integer', status);
      RETURN;
    IFEND;

{ Return the value of the validation field.

    integer_value := field_value.integer_value^;

{ Return the display format.

    integer_display_format := type_specification.integer_display_format^;

  PROCEND avp$get_integer_value;
?? TITLE := '    avp$get_job_class_value', EJECT ??
*copyc avh$get_job_class_value

  PROCEDURE [XDCL, #GATE] avp$get_job_class_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR job_classes: avt$name_list;
     VAR number_of_job_classes: avt$name_list_size;
     VAR batch_job_class_default: ost$name;
     VAR interactive_job_class_default: ost$name;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$job_class_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'job class', status);
      RETURN;
    IFEND;

{ Return as many of the job class validation values as will fit.

    FOR index := 1 TO UPPERBOUND (job_classes) DO
      IF index <= UPPERBOUND (field_value.job_classes^) THEN
        job_classes [index] := field_value.job_classes^ [index];
      ELSE
        job_classes [index] := osc$null_name;
      IFEND;
    FOREND;

{ Return the actual number of job classes.

    number_of_job_classes := UPPERBOUND (field_value.job_classes^);

{ Return the batch and interactive job class defaults.

    batch_job_class_default := field_value.batch_job_class_default^;
    interactive_job_class_default := field_value.interactive_job_class_default^;

  PROCEND avp$get_job_class_value;
?? TITLE := '    avp$get_labeled_names_value', EJECT ??
*copyc avh$get_labeled_names_value

  PROCEDURE [XDCL, #GATE] avp$get_labeled_names_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
         work_area: ^seq (*);
     VAR labeled_names:  ^avt$labeled_names_list;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      field_work_area: ^seq (*),
      index: avt$name_list_size,
      type_specification: avt$type_specification,
      work_area_ptr: ^seq (*);

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    PUSH field_work_area: [[REP 2 * avc$maximum_name_list_size OF avt$labeled_names]];
    RESET field_work_area;
    get_job_validation_field (caller_id, field_name, record_level, field_work_area, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$labeled_names_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'labeled name', status);
      RETURN;
    IFEND;

{ Return the labeled names field value.

    IF field_value.labeled_names <> NIL THEN
      work_area_ptr := work_area;
      NEXT labeled_names: [1 .. UPPERBOUND (field_value.labeled_names^)] IN work_area_ptr;
      FOR index := 1 TO UPPERBOUND (field_value.labeled_names^) DO
        NEXT labeled_names^ [index].label IN work_area_ptr;
        labeled_names^ [index].label^ := field_value.labeled_names^ [index].label^;

        NEXT labeled_names^ [index].names: [1 .. UPPERBOUND (field_value.labeled_names^ [index].names^)] IN
              work_area_ptr;
        labeled_names^ [index].names^ := field_value.labeled_names^ [index].names^;
      FOREND;
    ELSE
      labeled_names := NIL;
    IFEND;

  PROCEND avp$get_labeled_names_value;
?? TITLE := '    avp$get_limit_value', EJECT ??
*copyc avh$get_limit_value

  PROCEDURE [XDCL, #GATE] avp$get_limit_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR limit_value: avt$limit_value;
     VAR display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$limit_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'limit', status);
      RETURN;
    IFEND;

{ Return the value of the validation field.

    limit_value := field_value.limit_value^;

{ The following code is temporary.  It will be replaced when limit display
{ formats are taken from the type specifiation (in a future release).

    display_format.field_size := 10;
    display_format.kind := avc$integer_format;
    display_format.radix := 10;
    display_format.display_radix := FALSE;

  PROCEND avp$get_limit_value;
?? TITLE := '    avp$get_login_password_value', EJECT ??
*copyc avh$get_login_password_value

  PROCEDURE [XDCL, #GATE] avp$get_login_password_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR expiration_date: ost$date_time;
     VAR expiration_interval: pmt$time_increment;
     VAR maximum_expiration_interval: pmt$time_increment;
     VAR expiration_warning_interval: pmt$time_increment;
     VAR expired_password_chg_interval: pmt$time_increment;
     VAR change_date: ost$date_time;
     VAR attributes: avt$name_list;
     VAR number_of_attributes: avt$name_list_size;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$login_password_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'login password', status);
      RETURN;
    IFEND;

{ Return the values for the validation field.  The encrypted password value is
{ not returned for security reasons.

    expiration_date := field_value.login_password_exp_date^;
    expiration_interval := field_value.login_password_exp_interval^;
    maximum_expiration_interval := field_value.login_password_max_exp_interval^;
    expiration_warning_interval := field_value.login_password_exp_warning^;
    expired_password_chg_interval := field_value.login_password_exp_chg_interval^;
    IF field_value.login_password_change_date = NIL THEN
      change_date.year := LOWERVALUE (change_date.year);
      change_date.month := LOWERVALUE (change_date.month);
      change_date.day := LOWERVALUE (change_date.day);
      change_date.hour := LOWERVALUE (change_date.hour);
      change_date.minute := LOWERVALUE (change_date.minute);
      change_date.second := LOWERVALUE (change_date.second);
      change_date.millisecond := LOWERVALUE (change_date.millisecond);
    ELSE
      change_date := field_value.login_password_change_date^;
    IFEND;

{ Return as many password attributes as will fit.

    FOR index := 1 TO UPPERBOUND (attributes) DO
      IF index <= UPPERBOUND (field_value.login_password_attributes^) THEN
        attributes [index] := field_value.login_password_attributes^ [index];
      ELSE
        attributes [index] := osc$null_name;
      IFEND;
    FOREND;

{ Return the actual number of password attributes.

    number_of_attributes := UPPERBOUND (field_value.login_password_attributes^);

  PROCEND avp$get_login_password_value;
?? TITLE := '    avp$get_name_value', EJECT ??
*copyc avh$get_name_value

  PROCEDURE [XDCL, #GATE] avp$get_name_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR names: avt$name_list;
     VAR number_of_names: avt$name_list_size;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      index: avt$name_list_size,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$name_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'name', status);
      RETURN;
    IFEND;

{ Return as many names as will fit.

    FOR index := 1 TO UPPERBOUND (names) DO
      IF index <= UPPERBOUND (field_value.names^) THEN
        names [index] := field_value.names^ [index];
      ELSE
        names [index] := osc$null_name;
      IFEND;
    FOREND;

{ Return the actual number of names.

    number_of_names := UPPERBOUND (field_value.names^);

  PROCEND avp$get_name_value;
?? TITLE := '    avp$get_real_value', EJECT ??
*copyc avh$get_real_value

  PROCEDURE [XDCL, #GATE] avp$get_real_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR real_value: real;
     VAR display_format: avt$numeric_display_format;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$real_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'real', status);
      RETURN;
    IFEND;

{ Return the current field values.

    real_value := field_value.real_value^;

{ Return the display format.

    display_format := type_specification.real_display_format^;

  PROCEND avp$get_real_value;
?? TITLE := '    avp$get_string_value', EJECT ??
*copyc avh$get_string_value

  PROCEDURE [XDCL, #GATE] avp$get_string_value
    (    field_name: ost$name;
         record_level: avt$validation_record;
     VAR string_value: ost$string;
     VAR status: ost$status);

    VAR
      caller_id: ost$caller_identifier,
      field_value: avt$field_value,
      type_specification: avt$type_specification;

    status.normal := TRUE;

    #CALLER_ID (caller_id);

{ Get the field value and the type specification for the specified field.  Also
{ verify that the caller has suficient authority to read the value.

    get_job_validation_field (caller_id, field_name, record_level, {work_area=} NIL, field_value,
          type_specification, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Verify that the field is the correct type.

    IF type_specification.kind <> avc$string_kind THEN
      osp$set_status_abnormal ('AV', ave$incorrect_kind, field_name, status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'string', status);
      RETURN;
    IFEND;

{ Return the value of the validation field.

    IF field_value.string_value <> NIL THEN
      string_value.value := field_value.string_value^;
      string_value.size := #SIZE (field_value.string_value^);
    ELSE
      string_value.value := ' ';
      string_value.size := 0;
    IFEND;

  PROCEND avp$get_string_value;
?? OLDTITLE ??
?? TITLE := '  Helper procedures' ??
?? NEWTITLE := '    delete_record_utility_info_cmd', EJECT ??
{
{ PURPOSE:
{
{   This procedure deletes the entries for a specified field and command name
{ pair from the command table information stored in the record utility
{ information for a validation record.
{

  PROCEDURE delete_record_utility_info_cmd
    (    field_name: ost$name;
         procedure_name: ost$name;
     VAR record_utility_information: ^avt$utility_information;
     VAR status: ost$status);

    VAR
      command_index: integer,
      index: integer,
      new_index: integer,
      number_of_entries: integer,
      ordinal_to_delete: integer,
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      record_utility_info_entry: ^avt$record_utility_info_entry,
      record_utility_info_header: ^avt$record_utility_info_header;

    status.normal := TRUE;

{ Extract the header from the record utility information.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('ADD_NEW_RECORD_UTILITY_INFO_CMD', 'RECORD_UTILITY_INFO_HEADER',
            'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;

{ Extract the command table information from the record utility information.

    NEXT record_utility_info_array: [1 .. record_utility_info_header^.number_of_entries] IN
          record_utility_information;
    IF record_utility_info_array = NIL THEN
      corrupted_sequence ('ADD_NEW_RECORD_UTILITY_INFO_CMD', 'RECORD_UTILITY_INFORMATION',
            'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;

{ Search the command table to find the ordinal number for an entry
{ that matches the specified field name and procedure name.

    ordinal_to_delete := 0;

  /find_ordinal_number/
    FOR index := 1 TO record_utility_info_header^.number_of_entries DO
      IF ((field_name = record_utility_info_array^ [index].field_name) AND
            (procedure_name = record_utility_info_array^ [index].command_table_entry.procedure_name)) THEN
        ordinal_to_delete := record_utility_info_array^ [index].command_table_entry.ordinal;
        EXIT /find_ordinal_number/;
      IFEND;
    FOREND /find_ordinal_number/;

{ If a match is found delete all entries with the matching ordinal
{ and reduce the ordinal of all higher ordinal entries by one so
{ that the ordinals remain sequential.

    IF ordinal_to_delete <> 0 THEN
      record_utility_info_header^.number_of_commands := record_utility_info_header^.number_of_commands - 1;
      number_of_entries := record_utility_info_header^.number_of_entries;
      new_index := 1;
      FOR index := 1 TO number_of_entries DO
        IF record_utility_info_array^ [index].command_table_entry.ordinal = ordinal_to_delete THEN
          record_utility_info_header^.number_of_entries := record_utility_info_header^.number_of_entries - 1;
        ELSE
          IF record_utility_info_array^ [index].command_table_entry.ordinal > ordinal_to_delete THEN
            record_utility_info_array^ [index].command_table_entry.ordinal :=
                  record_utility_info_array^ [index].command_table_entry.ordinal - 1;
          IFEND;
          record_utility_info_array^ [new_index] := record_utility_info_array^ [index];
          new_index := new_index + 1;
        IFEND;
      FOREND;
    IFEND;

  PROCEND delete_record_utility_info_cmd;
?? TITLE := '    add_new_record_utility_info_cmd', EJECT ??
{
{ PURPOSE:
{
{   This procedure adds a command and its aliases to the command table
{ information stored in the record utility information for a validation record.
{

  PROCEDURE add_new_record_utility_info_cmd
    (    add_commands: avt$name_list;
         field_name: ost$name;
         procedure_name: ost$name;
     VAR record_utility_information: ^avt$utility_information;
     VAR status: ost$status);

    VAR
      command_index: integer,
      index: integer,
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      record_utility_info_entry: ^avt$record_utility_info_entry,
      record_utility_info_header: ^avt$record_utility_info_header;

    status.normal := TRUE;

{ Extract the header from the record utility information.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('ADD_NEW_RECORD_UTILITY_INFO_CMD', 'RECORD_UTILITY_INFO_HEADER',
            'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    IF record_utility_info_header^.number_of_entries > 0 THEN

{ Extract the command table information from the record utility information.

      NEXT record_utility_info_array: [1 .. record_utility_info_header^.number_of_entries] IN
            record_utility_information;
      IF record_utility_info_array = NIL THEN
        corrupted_sequence ('ADD_NEW_RECORD_UTILITY_INFO_CMD', 'RECORD_UTILITY_INFORMATION',
              'RECORD_UTILITY_INFORMATION', status);
        RETURN;
      IFEND;
    IFEND;

{ Add the new entries to the end of the command table information.

    record_utility_info_header^.number_of_commands := record_utility_info_header^.number_of_commands + 1;
    FOR command_index := 1 TO UPPERBOUND (add_commands) DO
      NEXT record_utility_info_entry IN record_utility_information;
      IF record_utility_info_entry = NIL THEN
        corrupted_sequence ('ADD_NEW_RECORD_UTILITY_INFO_CMD', 'RECORD_UTILITY_INFORMATION',
              'RECORD_UTILITY_INFORMATION', status);
        RETURN;
      IFEND;
      record_utility_info_entry^.field_name := field_name;
      record_utility_info_entry^.command_table_entry.name := add_commands [command_index];
      IF command_index = 1 THEN
        record_utility_info_entry^.command_table_entry.class := clc$nominal_entry;
      ELSEIF command_index = UPPERBOUND (add_commands) THEN
        record_utility_info_entry^.command_table_entry.class := clc$abbreviation_entry;
      ELSE
        record_utility_info_entry^.command_table_entry.class := clc$alias_entry;
      IFEND;
      record_utility_info_entry^.command_table_entry.availability := clc$advertised_entry;
      record_utility_info_entry^.command_table_entry.ordinal :=
            record_utility_info_header^.number_of_commands;
      record_utility_info_entry^.command_table_entry.log_option := clc$manually_log;
      record_utility_info_entry^.command_table_entry.call_method := clc$unlinked_call;
      record_utility_info_entry^.command_table_entry.procedure_name := procedure_name;
      record_utility_info_header^.number_of_entries := record_utility_info_header^.number_of_entries + 1;
    FOREND;

  PROCEND add_new_record_utility_info_cmd;
?? TITLE := '    add_names_to_name_list', EJECT ??
{
{ PURPOSE:
{
{   This procedure adds a list of names to a fixed size array of names.
{

  PROCEDURE add_names_to_name_list
    (    names: ^array [1 .. * ] of ost$name;
         parameter_name: string ( * <= osc$max_name_size);
     VAR name_list: array [1 .. avc$maximum_name_list_size] of ost$name;
     VAR number_of_names: 1 .. avc$maximum_name_list_size;
     VAR status: ost$status);

    VAR
      index: 1 .. avc$maximum_name_list_size,
      name_list_index: 1 .. avc$maximum_name_list_size;

    IF UPPERBOUND (names^) > 1 THEN
      FOR index := 1 TO UPPERBOUND (names^) DO
        IF names^ [index] = 'ALL' THEN
          osp$set_status_abnormal ('AV', cle$all_must_be_used_alone, parameter_name, status);
          RETURN;
        ELSEIF names^ [index] = 'NONE' THEN
          osp$set_status_abnormal ('AV', cle$none_must_be_used_alone, parameter_name, status);
          RETURN;
        IFEND;
      FOREND;
    IFEND;

  /add_name_to_name_list/
    FOR index := 1 TO UPPERBOUND (names^) DO

{ If the name to add is ALL make ALL the only entry in the name list.

      IF names^ [index] = 'ALL' THEN
        name_list [1] := 'ALL';
        number_of_names := 1;
        RETURN;
      ELSEIF names^ [index] = 'NONE' THEN

{ If the name to add is NONE then no action is necessary.

        RETURN;
      ELSEIF (number_of_names = 1) AND (name_list [1] = 'ALL') THEN

{ If the list already contains ALL then no action is necessary.

        RETURN;
      ELSEIF (number_of_names = 1) AND (name_list [1] = 'NONE') THEN

{ If the list contains NONE then put it as the only entry in the list.

        name_list [1] := names^ [index];
      ELSE

{ If the list already contains the name specified then no action is necessary.

        FOR name_list_index := 1 TO number_of_names DO
          IF name_list [name_list_index] = names^ [index] THEN
            CYCLE /add_name_to_name_list/;
          IFEND;
        FOREND;

{ Else add the new name to the next avialable spot in the list.

        number_of_names := number_of_names + 1;
        name_list [number_of_names] := names^ [index];
      IFEND;
    FOREND /add_name_to_name_list/;

  PROCEND add_names_to_name_list;
?? TITLE := '    change_labeled_names', EJECT ??
{
{ PURPOSE:
{
{   This procedure adds a list of labeled names to an existing list of labeled names.
{

  PROCEDURE change_labeled_names
    (    add_labeled_names: ^avt$labeled_names_list;
         delete_labeled_names: ^avt$labeled_names_list;
         field_value: avt$field_value;
     VAR work_area: ^seq (*);
     VAR labeled_names: ^avt$labeled_names_list;
     VAR status: ost$status);

    VAR
      add_entry_processed: ^array [1 .. *] of boolean,
      index1: 1 .. avc$maximum_name_list_size,
      index2: 1 .. avc$maximum_name_list_size,
      local_work_area: ^seq (*),
      name_list: ^avt$name_list,
      number_of_labeled_names: 0 .. avc$maximum_name_list_size,
      number_of_names: 1 .. avc$maximum_name_list_size;

    status.normal := TRUE;

{ Make an array to keep track of which adds have been processed.

    IF add_labeled_names <> NIL THEN
      PUSH add_entry_processed: [1 .. UPPERBOUND (add_labeled_names^)];
      FOR index1 := 1 TO UPPERBOUND (add_labeled_names^) DO
        add_entry_processed^ [index1] := FALSE;
      FOREND;
    IFEND;

{ Allocate a temporary array for holding a name list.

    PUSH name_list: [1 .. avc$maximum_name_list_size];

{ Initialize an array for holding the new list of labeled names.

    NEXT labeled_names: [1 .. avc$maximum_name_list_size] IN work_area;
    IF labeled_names = NIL THEN
      osp$set_status_abnormal ('AV', ave$record_too_large, '', status);
      RETURN;
    IFEND;
    FOR index1 := 1 TO avc$maximum_name_list_size DO
      labeled_names^ [index1].label := NIL;
      labeled_names^ [index1].names := NIL;
    FOREND;

{ Process each labeled name in the field value list.

    number_of_labeled_names := 0;
    IF (field_value.labeled_names <> NIL) AND (field_value.labeled_names^ [1].label^ <> 'NONE') THEN

    /process_entry/
      FOR index1 := 1 TO UPPERBOUND (field_value.labeled_names^) DO

{ Copy the current list of names to the temporary array.

        FOR index2 := 1 TO avc$maximum_name_list_size DO
          IF index2 <= UPPERBOUND (field_value.labeled_names^ [index1].names^) THEN
            name_list^ [index2] := field_value.labeled_names^ [index1].names^ [index2];
          ELSE
            name_list^ [index2] := osc$null_name;
          IFEND;
        FOREND;
        number_of_names := UPPERBOUND (field_value.labeled_names^ [index1].names^);

{ Delete any specified names from the temporary array.

        IF (delete_labeled_names <> NIL) AND (delete_labeled_names^ [1].label^ <> 'NONE') THEN
          FOR index2 := 1 TO UPPERBOUND (delete_labeled_names^) DO

{ If the field value is currently ALL then make sure specifics are not being deleted.

            IF (field_value.labeled_names^ [1].label^ = 'ALL') AND
                 (delete_labeled_names^ [index2].label^ <> 'ALL') THEN
              osp$set_status_condition (ave$cannot_delete_name_from_all, status);
              RETURN;
            IFEND;
            IF (delete_labeled_names^ [index2].label^ = field_value.labeled_names^ [index1].label^) OR
                  (delete_labeled_names^ [index2].label^ = 'ALL') THEN
              IF delete_labeled_names^ [index2].names <> NIL THEN
                delete_names_from_name_list (delete_labeled_names^ [index2].names, 'delete_labeled_names',
                    name_list^, number_of_names, status);
                IF NOT status.normal THEN
                  RETURN;
                IFEND;
              ELSE
                CYCLE /process_entry/; {Delete the label}
              IFEND;
            IFEND;
          FOREND;
        IFEND;

{ Add any specified names to the temporary array.

        IF add_labeled_names <> NIL THEN
          FOR index2 := 1 TO UPPERBOUND (add_labeled_names^) DO
            IF add_labeled_names^ [index2].label^ = field_value.labeled_names^ [index1].label^ THEN
              IF add_labeled_names^ [index2].names = NIL THEN
                number_of_names := 1;
                name_list^ [1] := 'ALL';
              ELSE
                add_names_to_name_list (add_labeled_names^ [index2].names, 'add_labeled_names', name_list^,
                      number_of_names, status);
                IF NOT status.normal THEN
                  RETURN;
                IFEND;
              IFEND;
              add_entry_processed^ [index2] := TRUE;
            IFEND;
          FOREND;
        IFEND;

{ Move the names temporary array to the labeled names temporary array;

        number_of_labeled_names := number_of_labeled_names + 1;
        NEXT labeled_names^ [number_of_labeled_names].label IN work_area;
        IF labeled_names^ [number_of_labeled_names].label = NIL THEN
          osp$set_status_abnormal ('AV', ave$record_too_large, '', status);
          RETURN;
        IFEND;
        labeled_names^ [number_of_labeled_names].label^ := field_value.labeled_names^ [index1].label^;
        NEXT labeled_names^ [number_of_labeled_names].names: [1 .. number_of_names] IN work_area;
        IF labeled_names^ [number_of_labeled_names].names = NIL THEN
          osp$set_status_abnormal ('AV', ave$record_too_large, '', status);
          RETURN;
        IFEND;
        FOR index2 := 1 TO number_of_names DO
          labeled_names^ [number_of_labeled_names].names^ [index2] := name_list^ [index2];
        FOREND;
      FOREND /process_entry/;
    IFEND;

{ Put the adds that did not have a match in the field value list into the temporary labeled names list.

    IF add_labeled_names <> NIL THEN

      FOR index1 := 1 TO UPPERBOUND (add_labeled_names^) DO
        IF (NOT add_entry_processed^ [index1]) AND
              (add_labeled_names^ [index1].label^ <> 'NONE') THEN

{ If the result value is currently ALL then make sure specifics are not being added to ALL.

          IF (number_of_labeled_names = 1) AND (labeled_names^ [1].label^ = 'ALL') AND
                ((UPPERBOUND (add_labeled_names^) > 1) OR (add_labeled_names^ [1].label^ <> 'ALL')) THEN
            osp$set_status_condition (ave$cannot_add_name_to_all, status);
            RETURN;
          IFEND;

{ If the result value is not currently ALL then make sure 'ALL' is not being added to a specific.

          IF (number_of_labeled_names >= 1) AND (labeled_names^ [1].label^ <> 'ALL') AND
                (add_labeled_names^ [1].label^ = 'ALL') THEN
            osp$set_status_condition (ave$cannot_add_all_to_name, status);
            RETURN;
          IFEND;

{ Null out the temporary name array, then use add names to name list to insure no duplicate names
{ were specified.

          FOR index2 := 1 TO avc$maximum_name_list_size DO
            name_list^ [index2] := osc$null_name;
          FOREND;
          name_list^ [1] := 'NONE';
          number_of_names := 1;
          FOR index2 := index1 TO UPPERBOUND (add_labeled_names^) DO
            IF add_labeled_names^ [index2].label^ = add_labeled_names^ [index1].label^ THEN
              IF add_labeled_names^ [index2].names = NIL THEN
                number_of_names := 1;
                name_list^ [1] := 'ALL';
              ELSE
                add_names_to_name_list (add_labeled_names^ [index2].names, 'add_labeled_names',
                      name_list^, number_of_names, status);
                IF NOT status.normal THEN
                  RETURN;
                IFEND;
              IFEND;
              add_entry_processed^ [index2] := TRUE;
            IFEND;
          FOREND;

{ Move the result to the output parameter.

          number_of_labeled_names := number_of_labeled_names + 1;
          NEXT labeled_names^ [number_of_labeled_names].label IN work_area;
          IF labeled_names^ [number_of_labeled_names].label = NIL THEN
            osp$set_status_abnormal ('AV', ave$record_too_large, '', status);
            RETURN;
          IFEND;
          labeled_names^ [number_of_labeled_names].label^ := add_labeled_names^ [index1].label^;
          NEXT labeled_names^ [number_of_labeled_names].names: [1 .. number_of_names] IN work_area;
          IF labeled_names^ [number_of_labeled_names].names = NIL THEN
            osp$set_status_abnormal ('AV', ave$record_too_large, '', status);
            RETURN;
          IFEND;
          FOR index2 := 1 TO number_of_names DO
            labeled_names^ [number_of_labeled_names].names^ [index2] := name_list^ [index2];
          FOREND;
        IFEND;
      FOREND;
    IFEND;

    IF number_of_labeled_names = 0 THEN
      number_of_labeled_names := 1;
      NEXT labeled_names^ [1].label IN work_area;
      IF labeled_names^ [1].label = NIL THEN
        osp$set_status_abnormal ('AV', ave$record_too_large, '', status);
        RETURN;
      IFEND;
      labeled_names^ [1].label^ := 'NONE';
      NEXT labeled_names^ [1].names: [1 .. 1] IN work_area;
      IF labeled_names^ [1].names = NIL THEN
        osp$set_status_abnormal ('AV', ave$record_too_large, '', status);
        RETURN;
      IFEND;
      labeled_names^ [1].names^ [1] := 'NONE';
    IFEND;

    local_work_area := work_area;
    RESET local_work_area TO labeled_names;
    NEXT labeled_names: [1 .. number_of_labeled_names] IN local_work_area;

  PROCEND change_labeled_names;

?? TITLE := '    avp$change_util_info_cmd_name', EJECT ??
{
{ PURPOSE:
{
{   This procedure changes the name of a command in the command table
{ information stored in the record utility information for a validation record.
{

  PROCEDURE [XDCL] avp$change_util_info_cmd_name
    (    command_name: ost$name;
         new_command_name: ost$name;
         validation_record_name: ost$name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      index: integer,
      record_utility_information: ^avt$utility_information,
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      record_utility_info_entry: ^avt$record_utility_info_entry,
      record_utility_info_header: ^avt$record_utility_info_header,
      utility_information: ^avt$utility_information,
      utility_information_size: integer;

    status.normal := TRUE;

{ Get the record utility information command table information.

    avp$get_desc_utility_info_size (validation_record_name, utility_information_size, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    PUSH record_utility_information: [[REP utility_information_size OF cell]];
    RESET record_utility_information;
    utility_information_size := #SIZE (record_utility_information^);
    avp$get_desc_utility_info (validation_record_name, record_utility_information, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Extract the header from the record utility information.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('CHANGE_UTILITY_INFO_FIELD_NAME', 'RECORD_UTILITY_INFO_HEADER',
            'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    IF record_utility_info_header^.number_of_entries > 0 THEN

{ Extract the command table information from the record utility information.

      NEXT record_utility_info_array: [1 .. record_utility_info_header^.number_of_entries] IN
            record_utility_information;
      IF record_utility_info_array = NIL THEN
        corrupted_sequence ('CHANGE_UTILITY_INFO_FIELD_NAME', 'RECORD_UTILITY_INFORMATION',
              'RECORD_UTILITY_INFORMATION', status);
        RETURN;
      IFEND;
    IFEND;

{ Change all entries with a matching command name.

    FOR index := 1 TO record_utility_info_header^.number_of_entries DO
      IF record_utility_info_array^ [index].command_table_entry.name = command_name THEN
        record_utility_info_array^ [index].command_table_entry.name := new_command_name;
      IFEND;
    FOREND;

{ Verify that a duplicate entry is not being added.

    sort_record_utility_information (record_utility_information, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Rewrite the record utility information command table information.

    avp$change_desc_utility_info (validation_record_name, utility_information, file_information,
          status);

  PROCEND avp$change_util_info_cmd_name;

?? TITLE := '    change_utility_info_field_name', EJECT ??
{
{ PURPOSE:
{
{   This procedure changes the name of a field in the command table
{ information stored in the record utility information for a validation record.
{

  PROCEDURE change_utility_info_field_name
    (    field_name: ost$name;
         new_field_name: ost$name;
     VAR record_utility_information: ^avt$utility_information;
     VAR status: ost$status);

    VAR
      index: integer,
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      record_utility_info_entry: ^avt$record_utility_info_entry,
      record_utility_info_header: ^avt$record_utility_info_header;

    status.normal := TRUE;

{ Extract the header from the record utility information.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('CHANGE_UTILITY_INFO_FIELD_NAME', 'RECORD_UTILITY_INFO_HEADER',
            'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    IF record_utility_info_header^.number_of_entries > 0 THEN

{ Extract the command table information from the record utility information.

      NEXT record_utility_info_array: [1 .. record_utility_info_header^.number_of_entries] IN
            record_utility_information;
      IF record_utility_info_array = NIL THEN
        corrupted_sequence ('CHANGE_UTILITY_INFO_FIELD_NAME', 'RECORD_UTILITY_INFORMATION',
              'RECORD_UTILITY_INFORMATION', status);
        RETURN;
      IFEND;
    IFEND;

{ Change all entries with a matching field name.

    FOR index := 1 TO record_utility_info_header^.number_of_entries DO
      IF record_utility_info_array^ [index].field_name = field_name THEN
        record_utility_info_array^ [index].field_name := new_field_name;
      IFEND;
    FOREND;

  PROCEND change_utility_info_field_name;
?? TITLE := '    corrupted_sequence', EJECT ??
{
{ PURPOSE:
{
{   This procedure builds an abnormal status variable used to report a
{ problem when accessing a sequence within the validation file.
{

  PROCEDURE corrupted_sequence
    (    procedure_name: string ( * );
         variable_name: string ( * );
         sequence_name: string ( * );
     VAR status: ost$status);

    osp$set_status_abnormal ('AV', ave$corrupted_sequence, procedure_name, status);
    osp$append_status_parameter (osc$status_parameter_delimiter, variable_name, status);
    osp$append_status_parameter (osc$status_parameter_delimiter, sequence_name, status);

  PROCEND corrupted_sequence;
?? TITLE := '    delete_names_from_name_list', EJECT ??
{
{ PURPOSE:
{
{   This procedure deletes a name from a fixed size array of names.
{

  PROCEDURE delete_names_from_name_list
    (    names: ^array [1 .. * ] of ost$name;
         parameter_name: string ( * <= osc$max_name_size);
     VAR name_list: array [1 .. avc$maximum_name_list_size] of ost$name;
     VAR number_of_names: 1 .. avc$maximum_name_list_size;
     VAR status: ost$status);

    VAR
      new_number_of_names: 0 .. avc$maximum_name_list_size,
      index: 1 .. avc$maximum_name_list_size,
      name_list_index: 1 .. avc$maximum_name_list_size;

    status.normal := TRUE;

    IF UPPERBOUND (names^) > 1 THEN
      FOR index := 1 TO UPPERBOUND (names^) DO
        IF names^ [index] = 'ALL' THEN
          osp$set_status_abnormal ('AV', cle$all_must_be_used_alone, parameter_name, status);
          RETURN;
        ELSEIF names^ [index] = 'NONE' THEN
          osp$set_status_abnormal ('AV', cle$none_must_be_used_alone, parameter_name, status);
          RETURN;
        IFEND;
      FOREND;
    IFEND;

    FOR index := 1 TO UPPERBOUND (names^) DO

{ If the name to delete is ALL make NONE the only entry in the name list.

      IF names^ [index] = 'ALL' THEN
        name_list [1] := 'NONE';
        number_of_names := 1;
        RETURN;
      ELSEIF names^ [index] = 'NONE' THEN

{ If the name to delete is NONE then no action is necessary.

        RETURN;
      ELSEIF (number_of_names = 1) AND (name_list [1] = 'ALL') AND (names^ [index] <> 'ALL') THEN

{ A specific name can not be deleted from a list containing ALL.

        osp$set_status_abnormal ('AV', ave$cannot_delete_name_from_all, '', status);
        RETURN;
      ELSE

{ Else delete the name from the list if it is found in the list.

        new_number_of_names := 0;
        FOR name_list_index := 1 TO number_of_names DO
          IF name_list [name_list_index] <> names^ [index] THEN
            new_number_of_names := new_number_of_names + 1;
            name_list [new_number_of_names] := name_list [name_list_index];
          IFEND;
        FOREND;

{ If the only entry in the list was deleted put NONE in the list.

        IF new_number_of_names = 0 THEN
          name_list [1] := 'NONE';
          new_number_of_names := 1;
        IFEND;

        number_of_names := new_number_of_names;
      IFEND;
    FOREND;

  PROCEND delete_names_from_name_list;
?? TITLE := '    determine_caller_authority', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to determine the authority of a caller of an
{ interface.
{

  PROCEDURE determine_caller_authority
    (    caller_id: ost$caller_identifier;
         account_name: ^avt$account_name;
         project_name: ^avt$project_name;
         user_name: ^ost$user_name;
         creation_account_name: ^avt$account_name;
         creation_project_name: ^avt$project_name;
     VAR caller_authority: avt$validation_authority);

    VAR
      account_administrator: boolean,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      executing_user_name: ost$user_identification,
      ignore_status: ost$status,
      processing_phase: clt$processing_phase,
      project_administrator: boolean,
      restricted_mainframe: boolean,
      user_administration_capability: boolean;

{ Caller authority is initialize to the least privileged authority possible.

    caller_authority := avc$any_authority;

{ If The caller is running in ring 3 or below system authority is assigned.

    IF caller_id.ring < osc$sj_ring_1 THEN
      caller_authority := avc$system_authority;
      RETURN;
    IFEND;

    processing_phase := clc$command_phase;
    clp$get_processing_phase (processing_phase, ignore_status);

    { If the caller is a system administrator or running in the system prolog or epilog and not on a
    { Soviet Nuclear Safety or China Weather machine, system administration authority is assigned.

    osp$check_for_desired_mf_class (osc$mc_china_or_soviet_class, restricted_mainframe);

    IF avp$system_administrator () OR (((processing_phase = clc$system_prolog_phase) OR
          (processing_phase = clc$system_epilog_phase)) AND (NOT restricted_mainframe)) THEN
      caller_authority := avc$system_admin_authority;
      RETURN;
    IFEND;

{ If the caller is a family administrator, family administrator authority is assigned.

    IF avp$family_administrator () THEN
      caller_authority := avc$family_admin_authority;
      RETURN;
    IFEND;

{ If an account name is supplied and the caller is an account administrator
{ for the specified account and running under the specified account then
{ account administrator authority is assigned.

    IF account_name <> NIL THEN
      executing_account_name := osc$null_name;
      pmp$get_account_project (executing_account_name, executing_project_name, ignore_status);
      account_administrator := FALSE;
      avp$get_capability (avc$account_administration, avc$account_member, account_administrator,
            ignore_status);
      IF (account_name^ = executing_account_name) AND (account_administrator OR
            (processing_phase <= clc$account_prolog_phase) OR (processing_phase = clc$account_epilog_phase))
            THEN
        caller_authority := avc$account_admin_authority;
        RETURN;
      IFEND;
      IF project_name <> NIL THEN

{ If a project name is supplied and the caller is a project administrator
{ for the specified project and running under the specified project then
{ project administrator authority is assigned.

        project_administrator := FALSE;
        avp$get_capability (avc$project_administration, avc$project_member, project_administrator,
              ignore_status);
        IF (account_name^ = executing_account_name) AND (project_name^ = executing_project_name) AND
              (project_administrator OR (processing_phase <= clc$project_prolog_phase) OR
              (processing_phase = clc$project_epilog_phase)) THEN
          caller_authority := avc$project_admin_authority;
          RETURN;
        IFEND;
      IFEND;
    IFEND;

{ If a creation account name is supplied and the caller is executing under the specified
{ account and is a user administrator for that account then user administration authority
{ is assigned.

    IF creation_account_name <> NIL THEN
      executing_account_name := osc$null_name;
      executing_project_name := osc$null_name;
      pmp$get_account_project (executing_account_name, executing_project_name, ignore_status);
      user_administration_capability := FALSE;
      avp$get_capability (avc$user_administration, avc$account_member, user_administration_capability,
            ignore_status);
      IF ((creation_account_name^ = executing_account_name) AND user_administration_capability) THEN
        caller_authority := avc$user_admin_authority;
        RETURN;
      IFEND;

{ If a creation project name is supplied and the caller is executing under the specified
{ project and is a user administrator for that project then user administration authority
{ is assigned.

      IF creation_project_name <> NIL THEN
        user_administration_capability := FALSE;
        avp$get_capability (avc$user_administration, avc$project_member, user_administration_capability,
              ignore_status);
        IF ((creation_account_name^ = executing_account_name) AND
              (creation_project_name^ = executing_project_name) AND user_administration_capability) THEN
          caller_authority := avc$user_admin_authority;
          RETURN;
        IFEND;
      IFEND;
    IFEND;

{ If a user name is supplied and the caller is running under the specified
{ user then user authority is assigned.

    IF user_name <> NIL THEN
      executing_user_name.user := osc$null_name;
      pmp$get_user_identification (executing_user_name, ignore_status);
      IF executing_user_name.user = user_name^ THEN
        caller_authority := avc$user_authority;
        RETURN;
      IFEND;
    IFEND;

  PROCEND determine_caller_authority;
?? TITLE := '    emit_chg_field_audit_statistic', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to emit the change field audit statistic.
{

  PROCEDURE emit_chg_field_audit_statistic
    (    description_record_name: ost$name;
         validation_file_reference: fst$file_reference;
         field_name: ost$name;
         changed_default_value: boolean;
         change_authority_p: ^avt$validation_authority;
         display_authority_p: ^avt$validation_authority;
         manage_authority_p: ^avt$validation_authority;
         status: ost$status);

    VAR
      audit_information: sft$audit_information;

    audit_information.audited_operation := sfc$ao_val_change_field;
    audit_information.change_validation_field.description_record_name_p := ^description_record_name;
    audit_information.change_validation_field.validation_file_p := ^validation_file_reference;
    audit_information.change_validation_field.field_name_p := ^field_name;
    IF changed_default_value THEN
      audit_information.change_validation_field.attribute := sfc$avfa_default_value;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;
    IF change_authority_p <> NIL THEN
      audit_information.change_validation_field.attribute := sfc$avfa_change_authority;
      audit_information.change_validation_field.new_authority := change_authority_p^;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;
    IF display_authority_p <> NIL THEN
      audit_information.change_validation_field.attribute := sfc$avfa_display_authority;
      audit_information.change_validation_field.new_authority := display_authority_p^;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;
    IF manage_authority_p <> NIL THEN
      audit_information.change_validation_field.attribute := sfc$avfa_manage_authority;
      audit_information.change_validation_field.new_authority := manage_authority_p^;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

  PROCEND emit_chg_field_audit_statistic;
?? TITLE := '    emit_chg_value_audit_statistic', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to emit the change value audit statistic.
{

  PROCEDURE emit_chg_value_audit_statistic
    (    description_record_name: ost$name;
         validation_file_reference: fst$file_reference;
         key: avt$validation_key;
         field_name: ost$name;
         status: ost$status);

    VAR
      audit_information: sft$audit_information;

    audit_information.audited_operation := sfc$ao_val_change_record;
    audit_information.change_val_record.description_record_name_p := ^description_record_name;
    audit_information.change_val_record.validation_file_p := ^validation_file_reference;
    audit_information.change_val_record.user_name_p := ^key.user_name;
    IF key.account_name = avc$high_value_name THEN
      audit_information.change_val_record.account_name_p := NIL;
    ELSE
      audit_information.change_val_record.account_name_p := ^key.account_name;
    IFEND;
    IF key.project_name = avc$high_value_name THEN
      audit_information.change_val_record.project_name_p := NIL;
    ELSE
      audit_information.change_val_record.project_name_p := ^key.project_name;
    IFEND;
    audit_information.change_val_record.field_name_p := ^field_name;
    sfp$emit_audit_statistic (audit_information, status);

  PROCEND emit_chg_value_audit_statistic;
?? TITLE := '    find_validation_record_info', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to find the validation record information
{ stored for a subutility session.
{

  PROCEDURE find_validation_record_info
    (    record_id: ost$name;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR status: ost$status);

    status.normal := TRUE;

{ Start at the begining of the validation record information chain.

    validation_record_info := avv$validation_record_info;

{ Search for a matching record id.

  /find_record_info/
    WHILE validation_record_info <> NIL DO
      IF validation_record_info^.record_id = record_id THEN
        EXIT /find_record_info/;
      IFEND;
      validation_record_info := validation_record_info^.forward;
    WHILEND /find_record_info/;

    IF validation_record_info = NIL THEN
      osp$set_status_abnormal ('AV', ave$missing_val_record_info, record_id, status);
    IFEND;

  PROCEND find_validation_record_info;
?? TITLE := '    get_field_description', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to get validation field description record
{ information from the validation record information chain if available, or directly
{ from the validation file.
{

  PROCEDURE get_field_description
    (    field_name: ost$name;
         record_name: ost$name;
         record_id: ost$name;
         work_area: ^seq (*);
         description_record: ^avt$template_file_record;
     VAR default_value: avt$field_value;
     VAR type_specification: avt$type_specification;
     VAR description: ost$string;
     VAR field_utility_information: avt$field_utility_information;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      field_utility_info_ptr: ^avt$field_utility_information,
      description_record_ptr: ^avt$template_file_record,
      descriptive_text: ^avt$descriptive_text,
      validation_record_info: ^avt$validation_record_info,
      utility_information: ^avt$utility_information,
      work_area_ptr: ^seq (*);

    status.normal := TRUE;

    IF record_id <> osc$null_name THEN

{ Get the description record from the previously stored validation record info.

      find_validation_record_info (record_id, validation_record_info, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      description_record_ptr := validation_record_info^.description_record;
    ELSE

{ Get the description record from the validation file.

      description_record_ptr := description_record;
      avp$get_description_record (record_name, description_record_ptr, file_information, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

{ Get the field description from the description record.

    work_area_ptr := work_area;
    avp$get_field_description (field_name, description_record_ptr, work_area_ptr, type_specification,
          default_value, descriptive_text, utility_information, status);
    IF status.normal OR (status.condition = ave$field_was_deleted) THEN

{ Access the field utility information.

      RESET utility_information;
      NEXT field_utility_info_ptr IN utility_information;
      IF field_utility_info_ptr = NIL THEN
        corrupted_sequence ('GET_FIELD_DESCRIPTION', 'FIELD_UTILITY_INFORMATION', 'UTILITY_INFORMATION',
              status);
        RETURN;
      IFEND;
      field_utility_information := field_utility_info_ptr^;

{ Access the field description.

      IF descriptive_text = NIL THEN
        description.value := ' ';
        description.size := 0;
      ELSE
        description.value := descriptive_text^;
        description.size := #SIZE (descriptive_text^);
      IFEND;
    IFEND;

  PROCEND get_field_description;
?? TITLE := '    get_job_validation_field', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the get the value of a validation field for the currently
{ executing job.
{

  PROCEDURE get_job_validation_field
    (    caller_id: ost$caller_identifier;
         field_name: ost$name;
         record_level: avt$validation_record;
         work_area: ^seq (*);
     VAR field_value: avt$field_value;
     VAR type_specification: avt$type_specification;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      data_record: ^avt$template_file_record,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      descriptive_text: ^avt$descriptive_text,
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name,
      field_utility_info_ptr: ^avt$field_utility_information,
      utility_information: ^avt$utility_information,
      work_area_ptr: ^seq (*);

    status.normal := TRUE;

{ Get pointers to the specified validation information.

    get_job_validation_record (caller_id, record_level, caller_authority, data_record, description_record,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Retrieve the field information for the specified field.

    work_area_ptr := work_area;
    avp$get_field (field_name, data_record, description_record, work_area_ptr, field_value,
          type_specification, default_value, descriptive_text, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Extract the display authority from the field utility information.

    NEXT field_utility_info_ptr IN utility_information;
    IF field_utility_info_ptr = NIL THEN
      corrupted_sequence ('INITIALIZE_GET_VALUE_INFO', 'DISPLAY_AUTHORITY', 'FIELD_UTILITY_INFORMATION',
            status);
      RETURN;
    IFEND;

{ Verify that the caller has the required authority.

    IF caller_authority < field_utility_info_ptr^.display_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

  PROCEND get_job_validation_field;
?? TITLE := '    get_job_validation_record', EJECT ??

{ PURPOSE:
{   This procedure returns pointers to the specified validation record for the currently executing job.

  PROCEDURE get_job_validation_record
    (    caller_id: ost$caller_identifier;
         record_level: avt$validation_record;
     VAR caller_authority: avt$validation_authority;
     VAR data_record: ^avt$template_file_record;
     VAR description_record: ^avt$template_file_record;
     VAR status: ost$status);

    VAR
      executing_account_name: avt$account_name,
      executing_project_name: avt$project_name;

    status.normal := TRUE;

{ Retrieve the executing job's account and project.

    pmp$get_account_project (executing_account_name, executing_project_name, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    CASE record_level OF
    = avc$user =

{ Find the user record stored in memory for the job.

      IF ((avv$user_data_record = NIL) OR (avv$user_description_record = NIL)) THEN
        osp$set_status_abnormal ('AV', ave$user_info_not_found, '', status);
        RETURN;
      IFEND;
      data_record := avv$user_data_record;
      description_record := avv$user_description_record;

      determine_caller_authority (caller_id, NIL, NIL, NIL, ^executing_account_name, ^executing_project_name,
            caller_authority);

{ Minimum authority is always set to user because the only option is to get the executing user's information.

      IF caller_authority < avc$user_authority THEN
        caller_authority := avc$user_authority;
      IFEND;

    = avc$account =

{ Find the account record stored in memory for the job.

      IF ((avv$account_data_record = NIL) OR (avv$account_description_record = NIL)) THEN
        osp$set_status_abnormal ('AV', ave$account_info_not_found, '', status);
        RETURN;
      IFEND;
      data_record := avv$account_data_record;
      description_record := avv$account_description_record;

      determine_caller_authority (caller_id, ^executing_account_name, NIL, NIL, NIL, NIL, caller_authority);

    = avc$account_member =

{ Find the account member record stored in memory for the job.

      IF ((avv$account_member_data_record = NIL) OR (avv$account_member_desc_record = NIL)) THEN
        osp$set_status_abnormal ('AV', ave$acct_member_info_not_found, '', status);
        RETURN;
      IFEND;
      data_record := avv$account_member_data_record;
      description_record := avv$account_member_desc_record;

      determine_caller_authority (caller_id, ^executing_account_name, NIL, NIL, NIL, NIL, caller_authority);

    = avc$project =

{ Find the project record stored in memory for the job.

      IF ((avv$project_data_record = NIL) OR (avv$project_description_record = NIL)) THEN
        osp$set_status_abnormal ('AV', ave$project_info_not_found, '', status);
        RETURN;
      IFEND;
      data_record := avv$project_data_record;
      description_record := avv$project_description_record;

      determine_caller_authority (caller_id, ^executing_account_name, ^executing_project_name, NIL, NIL, NIL,
            caller_authority);

    = avc$project_member =

{ Find the project member record stored in memory for the job.

      IF ((avv$project_member_data_record = NIL) OR (avv$project_member_desc_record = NIL)) THEN
        osp$set_status_abnormal ('AV', ave$proj_member_info_not_found, '', status);
        RETURN;
      IFEND;
      data_record := avv$project_member_data_record;
      description_record := avv$project_member_desc_record;

      determine_caller_authority (caller_id, ^executing_account_name, ^executing_project_name, NIL, NIL, NIL,
            caller_authority);
    ELSE
      osp$set_status_abnormal ('AV', ave$unknown_validation_record, '', status);
      RETURN;
    CASEND;

  PROCEND get_job_validation_record;
?? TITLE := '    init_get_display_value_info', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the get field display value interfaces to
{ perform common routines.
{
  PROCEDURE init_get_display_value_info
    (    field_name: ost$name;
         record_id: ost$name;
         work_area: ^seq (*);
     VAR field_value: avt$field_value;
     VAR type_specification: avt$type_specification;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      descriptive_text: ^avt$descriptive_text,
      field_utility_info_ptr: ^avt$field_utility_information,
      field_value_list_entry: ^avt$field_value_list_entry,
      utility_information: ^avt$utility_information,
      validation_record_info: ^avt$validation_record_info,
      work_area_ptr: ^seq (*);

    status.normal := TRUE;

{ Find the information for this subutility session within the validation
{ record information chain.

    find_validation_record_info (record_id, validation_record_info, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Retrieve the current field value of the specified field from the validation record.

    work_area_ptr := work_area;
    avp$get_field (field_name, validation_record_info^.data_record,
          validation_record_info^.description_record, work_area, field_value, type_specification,
          default_value, descriptive_text, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Get the display authority for the field.

    RESET utility_information;
    NEXT field_utility_info_ptr IN utility_information;
    IF field_utility_info_ptr = NIL THEN
      corrupted_sequence ('INITIALIZE_CHANGE_VALUE_INFO', 'CHANGE_AUTHORITY', 'FIELD_UTILITY_INFORMATION',
            status);
      RETURN;
    IFEND;

{ Verify that the caller has the required authority.

    IF validation_record_info^.caller_authority < field_utility_info_ptr^.display_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Reset the field value to the last value specified by any subutility
{ session updates for this field.

    field_value_list_entry := validation_record_info^.field_value_list;

  /find_existing_field_value/
    WHILE field_value_list_entry <> NIL DO
      IF field_value_list_entry^.field_name = field_name THEN
        field_value := field_value_list_entry^.field_value;
        EXIT /find_existing_field_value/;
      IFEND;
      field_value_list_entry := field_value_list_entry^.forward;
    WHILEND /find_existing_field_value/;

  PROCEND init_get_display_value_info;
?? TITLE := '    initialize_change_value_info', EJECT ??
{
{ PURPOSE:
{   This procedure is used by the change field value interfaces to
{ perform common routines.
{

  PROCEDURE initialize_change_value_info
    (    field_name: ost$name;
         record_id: ost$name;
         work_area: ^seq (*);
     VAR type_specification: avt$type_specification;
     VAR field_value_list_entry: ^avt$field_value_list_entry;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      descriptive_text: ^avt$descriptive_text,
      field_utility_info_ptr: ^avt$field_utility_information,
      field_value: avt$field_value,
      found_existing_field_value: boolean,
      utility_information: ^avt$utility_information,
      work_area_ptr: ^seq (*);

    status.normal := TRUE;

{ Find the information for this subutility session within the validation
{ record information chain.

    find_validation_record_info (record_id, validation_record_info, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Get the current field values.

    work_area_ptr := work_area;
    avp$get_field (field_name, validation_record_info^.data_record,
          validation_record_info^.description_record, work_area_ptr, field_value, type_specification,
          default_value, descriptive_text, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Retrieve the change authority from the field utility information.

    RESET utility_information;
    NEXT field_utility_info_ptr IN utility_information;
    IF field_utility_info_ptr = NIL THEN
      corrupted_sequence ('INITIALIZE_CHANGE_VALUE_INFO', 'CHANGE_AUTHORITY', 'FIELD_UTILITY_INFORMATION',
            status);
      RETURN;
    IFEND;
    IF validation_record_info^.caller_authority < field_utility_info_ptr^.change_authority THEN
      osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
      RETURN;
    IFEND;

{ Find any previous changes to this field for this subutility session.

    field_value_list_entry := validation_record_info^.field_value_list;
    found_existing_field_value := FALSE;

  /find_existing_field_value/
    WHILE field_value_list_entry <> NIL DO
      IF field_value_list_entry^.field_name = field_name THEN
        found_existing_field_value := TRUE;
        EXIT /find_existing_field_value/;
      IFEND;
      field_value_list_entry := field_value_list_entry^.forward;
    WHILEND /find_existing_field_value/;

{ Initialize a field value list entry with the current value if one was not found.

    IF NOT found_existing_field_value THEN
      NEXT field_value_list_entry IN validation_record_info^.work_area.sequence_pointer;
      field_value_list_entry^.field_name := field_name;
      field_value_list_entry^.field_value := field_value;
      field_value_list_entry^.forward := validation_record_info^.field_value_list;
      validation_record_info^.field_value_list := field_value_list_entry;
    IFEND;

  PROCEND initialize_change_value_info;
?? TITLE := '    initialize_validation_fields', EJECT ??
{
{ PURPOSE:
{
{   This procedure is called when opening a new validation file to create the
{ system defined validation fields.
{

  PROCEDURE initialize_validation_fields
    (    family_name: ost$family_name;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      description: ^avt$descriptive_text,
      description_string: ost$string,
      field_utility_information: avt$field_utility_information,
      string_value: ost$string,
      type_specification: avt$type_specification;

    status.normal := TRUE;

{ User fields.

    description_string.value := avc$accounting_admin_descr;
    description_string.size := clp$trimmed_string_size (avc$accounting_admin_descr);
    avp$create_capability_field (avc$accounting_administration, avc$user_record_name,
          avc$accounting_admin_default, description_string, avc$user_authority, avc$system_admin_authority,
          avc$system_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$application_admin_descr;
    description_string.size := clp$trimmed_string_size (avc$application_admin_descr);
    avp$create_capability_field (avc$application_administration, avc$user_record_name,
          avc$application_admin_default, description_string, avc$user_authority, avc$system_admin_authority,
          avc$system_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$configuration_admin_descr;
    description_string.size := clp$trimmed_string_size (avc$configuration_admin_descr);
    avp$create_capability_field (avc$configuration_admin, avc$user_record_name,
          avc$configuration_admin_default, description_string, avc$user_authority,
          avc$system_admin_authority, avc$system_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$cpu_time_limit_description;
    description_string.size := clp$trimmed_string_size (avc$cpu_time_limit_description);
    avp$create_accum_limit_field (avc$cpu_time_limit, avc$user_record_name, avc$maximum_cpu_default,
          avc$maximum_cpu_default, avc$maximum_cpu_default, avc$cpu_limit_name_default,
          avc$cpu_job_limits_apply_def, NIL, avc$minimum_cpu_default, avc$maximum_cpu_default,
          avc$cpu_total_limit_applies_def, avc$cpu_tot_lim_stops_login_def, avc$cpu_time_limit_chg_cmd,
          avc$cpu_time_limit_dis_cmd, description_string, avc$user_authority, avc$family_admin_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$creation_acct_proj_descr;
    description_string.size := clp$trimmed_string_size (avc$creation_acct_proj_descr);
    avp$create_acct_proj_field (avc$creation_account_project, avc$user_record_name,
          avc$default_account_default, avc$default_project_default, avc$creation_acct_proj_chg_cmd,
          avc$creation_acct_proj_dis_cmd, description_string, avc$user_admin_authority,
          avc$user_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$default_acct_proj_descr;
    description_string.size := clp$trimmed_string_size (avc$default_acct_proj_descr);
    avp$create_acct_proj_field (avc$default_account_project, avc$user_record_name,
          avc$default_account_default, avc$default_project_default, avc$default_acct_proj_chg_cmd,
          avc$default_acct_proj_dis_cmd, description_string, avc$user_authority, avc$user_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$dual_state_prompt_descr;
    description_string.size := clp$trimmed_string_size (avc$dual_state_prompt_descr);
    avp$create_capability_field (avc$dual_state_prompt, avc$user_record_name, avc$dual_state_prompt_default,
          description_string, avc$user_authority, avc$user_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$engineering_operation_descr;
    description_string.size := clp$trimmed_string_size (avc$engineering_operation_descr);
    avp$create_capability_field (avc$engineering_operation, avc$user_record_name,
          avc$engineering_operation_def, description_string, avc$user_authority,
          avc$system_admin_authority, avc$system_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$explicit_remote_file_descr;
    description_string.size := clp$trimmed_string_size (avc$explicit_remote_file_descr);
    avp$create_capability_field (avc$explicit_remote_file, avc$user_record_name, avc$explicit_remote_file_def,
          description_string, avc$user_authority, avc$family_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$family_admin_description;
    description_string.size := clp$trimmed_string_size (avc$family_admin_description);
    avp$create_capability_field (avc$family_administration, avc$user_record_name, avc$family_admin_default,
          description_string, avc$user_authority, avc$family_admin_authority, avc$system_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$implicit_remote_file_descr;
    description_string.size := clp$trimmed_string_size (avc$implicit_remote_file_descr);
    avp$create_capability_field (avc$implicit_remote_file, avc$user_record_name, avc$implicit_remote_file_def,
          description_string, avc$user_authority, avc$family_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$job_class_description;
    description_string.size := clp$trimmed_string_size (avc$job_class_description);
    avp$create_job_class_field (avc$job_class, avc$user_record_name, avc$job_class_defaults,
          avc$batch_job_class_default, avc$interactive_job_class_def, avc$common_job_class_defaults,
          avc$job_class_chg_cmd, avc$job_class_dis_cmd, description_string, avc$user_authority,
          avc$family_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$job_dest_usages_descr;
    description_string.size := clp$trimmed_string_size (avc$job_dest_usages_descr);
    avp$create_name_field (avc$job_destination_usages, avc$user_record_name, avc$job_destination_usages_def,
          avc$jdu_min_number_of_names, avc$jdu_max_number_of_names, avc$job_dest_usages_names_def,
          avc$job_dest_usages_chg_cmd, avc$job_dest_usages_dis_cmd, description_string, avc$user_authority,
          avc$family_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$link_attrib_charge_descr;
    description_string.size := clp$trimmed_string_size (avc$link_attrib_charge_descr);
    avp$create_string_field (avc$link_attribute_charge, avc$user_record_name, avc$link_attribute_default,
          avc$link_attribute_minimum_size, avc$link_attribute_maximum_size, avc$link_attrib_charge_chg_cmd,
          avc$link_attrib_charge_dis_cmd, description_string, avc$user_authority, avc$user_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    string_value.value := family_name;
    string_value.size := clp$trimmed_string_size (family_name);
    description_string.value := avc$link_attrib_family_descr;
    description_string.size := clp$trimmed_string_size (avc$link_attrib_family_descr);
    avp$create_string_field (avc$link_attribute_family, avc$user_record_name, string_value,
          avc$link_attribute_minimum_size, avc$link_attribute_maximum_size, avc$link_attrib_family_chg_cmd,
          avc$link_attrib_family_dis_cmd, description_string, avc$user_authority, avc$user_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$link_attrib_password_descr;
    description_string.size := clp$trimmed_string_size (avc$link_attrib_password_descr);
    avp$create_string_field (avc$link_attribute_password, avc$user_record_name, avc$link_attribute_default,
          avc$link_attribute_minimum_size, avc$link_attribute_maximum_size, avc$link_attrib_pw_chg_cmd,
          avc$link_attrib_pw_dis_cmd, description_string, avc$system_authority, avc$user_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$link_attrib_project_descr;
    description_string.size := clp$trimmed_string_size (avc$link_attrib_project_descr);
    avp$create_string_field (avc$link_attribute_project, avc$user_record_name, avc$link_attribute_default,
          avc$link_attribute_minimum_size, avc$link_attribute_maximum_size, avc$link_attrib_project_chg_cmd,
          avc$link_attrib_project_dis_cmd, description_string, avc$user_authority, avc$user_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$link_attrib_user_descr;
    description_string.size := clp$trimmed_string_size (avc$link_attrib_user_descr);
    avp$create_string_field (avc$link_attribute_user, avc$user_record_name, avc$link_attribute_default,
          avc$link_attribute_minimum_size, avc$link_attribute_maximum_size, avc$link_attrib_user_chg_cmd,
          avc$link_attrib_user_dis_cmd, description_string, avc$user_authority, avc$user_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$login_password_description;
    description_string.size := clp$trimmed_string_size (avc$login_password_description);
    avp$create_login_password_field (avc$login_password, avc$user_record_name, avc$login_password_default,
          avc$expiration_date_default, avc$exp_interval_default, avc$max_exp_interval_default,
          avc$exp_warning_default, avc$exp_chg_interval_default, avc$login_pass_attribute_def,
          avc$login_password_chg_cmd, avc$login_password_dis_cmd, description_string, avc$user_authority,
          avc$user_authority, avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$magnetic_tape_limit_descr;
    description_string.size := clp$trimmed_string_size (avc$magnetic_tape_limit_descr);
    avp$create_accum_limit_field (avc$magnetic_tape_limit, avc$user_record_name,
          avc$magnetic_tape_max_default, avc$magnetic_tape_max_default, avc$magnetic_tape_max_default,
          avc$mt_limit_name_default,
          avc$mt_job_limits_apply_def, NIL, avc$magnetic_tape_min_default, avc$magnetic_tape_max_default,
          avc$mt_total_limit_applies_def, avc$mt_tot_lim_stops_login_def, avc$magnetic_tape_limit_chg_cmd,
          avc$magnetic_tape_limit_dis_cmd, description_string, avc$user_authority, avc$family_admin_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$mailve_administration_descr;
    description_string.size := clp$trimmed_string_size (avc$mailve_administration_descr);
    avp$create_name_field (avc$mailve_administration, avc$user_record_name, avc$mailve_admin_names_def,
          avc$mailve_min_number_of_names, avc$mailve_max_number_of_names, avc$mailve_common_names_def,
          avc$mailve_admin_chg_cmd, avc$mailve_admin_dis_cmd, description_string, avc$user_authority,
          avc$system_admin_authority, avc$system_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$mailve_dist_list_limit_desc;
    description_string.size := clp$trimmed_string_size (avc$mailve_dist_list_limit_desc);
    avp$create_limit_field (avc$mailve_dist_list_limit, avc$user_record_name,
          avc$mailve_dist_list_limit_def, avc$mailve_dist_list_min_def, avc$mailve_dist_list_max_def,
          avc$mailve_dist_list_chg_cmd, avc$mailve_dist_list_dis_cmd, description_string,
          avc$user_authority, avc$family_admin_authority, avc$family_admin_authority, avc$system_authority,
          file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$mailve_mailbox_limit_descr;
    description_string.size := clp$trimmed_string_size (avc$mailve_mailbox_limit_descr);
    avp$create_limit_field (avc$mailve_mailbox_limit, avc$user_record_name,
          avc$mailve_mailbox_limit_def, avc$mailve_mailbox_lim_min_def, avc$mailve_mailbox_lim_max_def,
          avc$mailve_mailbox_lim_chg_cmd, avc$mailve_mailbox_lim_dis_cmd, description_string,
          avc$user_authority, avc$family_admin_authority, avc$family_admin_authority, avc$system_authority,
          file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$mailve_retention_limit_desc;
    description_string.size := clp$trimmed_string_size (avc$mailve_retention_limit_desc);
    avp$create_limit_field (avc$mailve_retention_limit, avc$user_record_name,
          avc$mailve_retention_limit_def, avc$mailve_retention_min_def, avc$mailve_retention_max_def,
          avc$mailve_retention_chg_cmd, avc$mailve_retention_dis_cmd, description_string,
          avc$user_authority, avc$family_admin_authority, avc$family_admin_authority, avc$system_authority,
          file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$network_applic_mgmt_descr;
    description_string.size := clp$trimmed_string_size (avc$network_applic_mgmt_descr);
    avp$create_capability_field (avc$network_applic_management, avc$user_record_name,
          avc$network_applic_mgmt_def, description_string, avc$user_authority, avc$system_admin_authority,
          avc$system_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$network_operation_descr;
    description_string.size := clp$trimmed_string_size (avc$network_operation_descr);
    avp$create_capability_field (avc$network_operation, avc$user_record_name, avc$network_operation_default,
          description_string, avc$user_authority, avc$system_admin_authority, avc$system_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$ntf_operation_description;
    description_string.size := clp$trimmed_string_size (avc$ntf_operation_description);
    avp$create_capability_field (avc$ntf_operation, avc$user_record_name, avc$ntf_operation_default,
          description_string, avc$user_authority, avc$system_admin_authority, avc$system_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$output_dest_usages_descr;
    description_string.size := clp$trimmed_string_size (avc$output_dest_usages_descr);
    avp$create_name_field (avc$output_destination_usages, avc$user_record_name, avc$output_dest_usages_def,
          avc$odu_min_number_of_names, avc$odu_max_number_of_names, avc$output_dest_usage_names_def,
          avc$output_dest_usages_chg_cmd, avc$output_dest_usages_dis_cmd, description_string,
          avc$user_authority, avc$family_admin_authority, avc$family_admin_authority, avc$system_authority,
          file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$removable_media_access_desc;
    description_string.size := clp$trimmed_string_size (avc$removable_media_access_desc);
    avp$create_labeled_names_field (avc$removable_media_access, avc$user_record_name,
          avc$removable_media_access_def, avc$rma_valid_groups_default, avc$rma_valid_access_modes_def,
          avc$rma_change_commands, avc$rma_display_commands,
          description_string, avc$user_authority, avc$family_admin_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$removable_media_admin_descr;
    description_string.size := clp$trimmed_string_size (avc$removable_media_admin_descr);
    avp$create_capability_field (avc$removable_media_admin, avc$user_record_name,
          avc$removable_media_admin_def, description_string, avc$user_authority, avc$system_admin_authority,
          avc$system_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$removable_media_oper_descr;
    description_string.size := clp$trimmed_string_size (avc$removable_media_oper_descr);
    avp$create_capability_field (avc$removable_media_operation, avc$user_record_name,
          avc$removable_media_oper_def, description_string, avc$user_authority, avc$system_admin_authority,
          avc$system_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$perm_file_space_limit_descr;
    description_string.size := clp$trimmed_string_size (avc$perm_file_space_limit_descr);
    avp$create_accum_limit_field (avc$permanent_file_space_limit, avc$user_record_name,
          avc$maximum_pfs_default, avc$maximum_pfs_default, avc$maximum_pfs_default,
          avc$pfs_limit_name_default, avc$pfs_job_limits_apply_def, NIL, avc$minimum_pfs_default,
          avc$maximum_pfs_default, avc$pfs_total_limit_applies_def, avc$pfs_tot_lim_stops_login_def,
          avc$perm_file_space_chg_cmd, avc$perm_file_space_dis_cmd, description_string, avc$user_authority,
          avc$family_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$permit_level_description;
    description_string.size := clp$trimmed_string_size (avc$permit_level_description);
    avp$create_name_field (avc$permit_level, avc$user_record_name, avc$permit_level_names_def,
          avc$pl_min_number_of_names, avc$pl_max_number_of_names, avc$permit_level_com_names_def,
          avc$permit_level_chg_cmd, avc$permit_level_dis_cmd, description_string, avc$user_authority,
          avc$family_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$ring_privilege_description;
    description_string.size := clp$trimmed_string_size (avc$ring_privilege_description);
    avp$create_ring_privilege_field (avc$ring_privileges, avc$user_record_name, avc$minimum_ring_default,
          avc$nominal_ring_default, avc$ring_privilege_chg_cmd, avc$ring_privilege_dis_cmd,
          description_string, avc$user_authority, avc$system_admin_authority, avc$system_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$scheduling_admin_descr;
    description_string.size := clp$trimmed_string_size (avc$scheduling_admin_descr);
    avp$create_capability_field (avc$scheduling_administration, avc$user_record_name,
          avc$scheduling_admin_default, description_string, avc$user_authority, avc$system_admin_authority,
          avc$system_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$sru_limit_description;
    description_string.size := clp$trimmed_string_size (avc$sru_limit_description);
    avp$create_accum_limit_field (avc$sru_limit, avc$user_record_name, avc$maximum_sru_default,
          avc$maximum_sru_default, avc$maximum_sru_default, avc$sru_limit_name_default,
          avc$sru_job_limits_apply_def, NIL, avc$minimum_sru_default, avc$maximum_sru_default,
          avc$sru_total_limit_applies_def, avc$sru_tot_lim_stops_login_def, avc$sru_limit_chg_cmd,
          avc$sru_limit_dis_cmd, description_string, avc$user_authority, avc$family_admin_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$station_operation_descr;
    description_string.size := clp$trimmed_string_size (avc$station_operation_descr);
    avp$create_capability_field (avc$station_operation, avc$user_record_name, avc$station_operation_default,
          description_string, avc$user_authority, avc$family_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$system_admin_description;
    description_string.size := clp$trimmed_string_size (avc$system_admin_description);
    avp$create_capability_field (avc$system_administration, avc$user_record_name, avc$system_admin_default,
          description_string, avc$user_authority, avc$system_admin_authority, avc$system_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$system_displays_description;
    description_string.size := clp$trimmed_string_size (avc$system_displays_description);
    avp$create_capability_field (avc$system_displays, avc$user_record_name, avc$system_displays_default,
          description_string, avc$user_authority, avc$system_admin_authority, avc$system_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$system_operation_descr;
    description_string.size := clp$trimmed_string_size (avc$system_operation_descr);
    avp$create_capability_field (avc$system_operation, avc$user_record_name, avc$system_operation_default,
          description_string, avc$user_authority, avc$system_admin_authority, avc$system_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$task_limit_description;
    description_string.size := clp$trimmed_string_size (avc$task_limit_description);
    avp$create_accum_limit_field (avc$task_limit, avc$user_record_name, avc$default_task_default,
          avc$default_task_default, avc$maximum_task_default, avc$task_limit_name_default,
          avc$task_job_limits_apply_def, NIL, avc$minimum_task_default, avc$maximum_task_default,
          avc$tas_total_limit_applies_def, avc$tas_tot_lim_stops_login_def, avc$task_limit_chg_cmd,
          avc$task_limit_dis_cmd, description_string, avc$user_authority, avc$family_admin_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$temp_file_space_limit_descr;
    description_string.size := clp$trimmed_string_size (avc$temp_file_space_limit_descr);
    avp$create_accum_limit_field (avc$temporary_file_space_limit, avc$user_record_name,
          avc$maximum_tfs_default, avc$maximum_tfs_default, avc$maximum_tfs_default,
          avc$tfs_limit_name_default, avc$tfs_job_limits_apply_def, NIL, avc$minimum_tfs_default,
          avc$maximum_tfs_default, avc$tfs_total_limit_applies_def, avc$tfs_tot_lim_stops_login_def,
          avc$temp_file_space_chg_cmd, avc$temp_file_space_dis_cmd, description_string, avc$user_authority,
          avc$family_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$terminal_timeout_limit_desc;
    description_string.size := clp$trimmed_string_size (avc$terminal_timeout_limit_desc);
    avp$create_limit_field (avc$terminal_timeout_limit, avc$user_record_name,
          avc$terminal_timeout_limit_def, avc$terminal_timeout_min_def, avc$terminal_timeout_max_def,
          avc$terminal_timeout_chg_cmd, avc$terminal_timeout_dis_cmd, description_string,
          avc$user_authority, avc$family_admin_authority, avc$family_admin_authority, avc$system_authority,
          file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$timesharing_description;
    description_string.size := clp$trimmed_string_size (avc$timesharing_description);
    avp$create_capability_field (avc$timesharing, avc$user_record_name, avc$timesharing_default,
          description_string, avc$user_authority, avc$family_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$user_epilog_description;
    description_string.size := clp$trimmed_string_size (avc$user_epilog_description);
    avp$create_file_field (avc$user_epilog, avc$user_record_name, avc$user_epilog_default,
          avc$user_epilog_chg_cmd, avc$user_epilog_dis_cmd, description_string, avc$user_authority,
          avc$user_authority, avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$user_prolog_description;
    description_string.size := clp$trimmed_string_size (avc$user_prolog_description);
    avp$create_file_field (avc$user_prolog, avc$user_record_name, avc$user_prolog_default,
          avc$user_prolog_chg_cmd, avc$user_prolog_dis_cmd, description_string, avc$user_authority,
          avc$user_authority, avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Account fields.

    description_string.value := avc$account_epilog_description;
    description_string.size := clp$trimmed_string_size (avc$account_epilog_description);
    avp$create_file_field (avc$account_epilog, avc$account_record_name, avc$account_epilog_default,
          avc$account_epilog_chg_cmd, avc$account_epilog_dis_cmd, description_string,
          avc$account_admin_authority, avc$account_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$account_prolog_description;
    description_string.size := clp$trimmed_string_size (avc$account_prolog_description);
    avp$create_file_field (avc$account_prolog, avc$account_record_name, avc$account_prolog_default,
          avc$account_prolog_chg_cmd, avc$account_prolog_dis_cmd, description_string,
          avc$account_admin_authority, avc$account_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Project fields.

    description_string.value := avc$project_epilog_description;
    description_string.size := clp$trimmed_string_size (avc$project_epilog_description);
    avp$create_file_field (avc$project_epilog, avc$project_record_name, avc$project_epilog_default,
          avc$project_epilog_chg_cmd, avc$project_epilog_dis_cmd, description_string,
          avc$project_admin_authority, avc$project_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$project_prolog_description;
    description_string.size := clp$trimmed_string_size (avc$project_prolog_description);
    avp$create_file_field (avc$project_prolog, avc$project_record_name, avc$project_prolog_default,
          avc$project_prolog_chg_cmd, avc$project_prolog_dis_cmd, description_string,
          avc$project_admin_authority, avc$project_admin_authority, avc$family_admin_authority,
          avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Account member fields.

    description_string.value := avc$account_admin_description;
    description_string.size := clp$trimmed_string_size (avc$account_admin_description);
    avp$create_capability_field (avc$account_administration, avc$account_member_record_name,
          avc$account_admin_default, description_string, avc$account_admin_authority,
          avc$account_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$user_admin_acct_descr;
    description_string.size := clp$trimmed_string_size (avc$user_admin_acct_descr);
    avp$create_capability_field (avc$user_administration, avc$account_member_record_name,
          avc$user_admin_default, description_string, avc$account_admin_authority, avc$family_admin_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Project member fields.

    description_string.value := avc$project_admin_description;
    description_string.size := clp$trimmed_string_size (avc$project_admin_description);
    avp$create_capability_field (avc$project_administration, avc$project_member_record_name,
          avc$project_admin_default, description_string, avc$project_admin_authority,
          avc$project_admin_authority, avc$family_admin_authority, avc$system_authority, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    description_string.value := avc$user_admin_proj_descr;
    description_string.size := clp$trimmed_string_size (avc$user_admin_proj_descr);
    avp$create_capability_field (avc$user_administration, avc$project_member_record_name,
          avc$user_admin_default, description_string, avc$project_admin_authority, avc$family_admin_authority,
          avc$family_admin_authority, avc$system_authority, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND initialize_validation_fields;
?? TITLE := '    initialize_validation_records', EJECT ??
{
{ PURPOSE:
{
{   This procedure is called when opening a new validation file to create the
{ system defined validation records.
{

  PROCEDURE initialize_validation_records
    (VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_information: ^avt$utility_information,
      utility_information: ^avt$utility_information;

    status.normal := TRUE;

{ Build User description record.

    PUSH record_utility_information: [[REP 1 OF avt$record_utility_info_header, REP
          (avc$maximum_field_count * 2) OF avt$record_utility_info_entry]];
    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('INITIALIZE_VALIDATION_RECORDS', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    record_utility_info_header^.number_of_commands := 0;
    record_utility_info_header^.number_of_entries := 0;

    add_new_record_utility_info_cmd (avc$end_change_user_commands, osc$null_name, avc$end_subutility_command,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_descr_cmds, osc$null_name,
          avc$display_field_description, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_names_cmds, osc$null_name, avc$display_field_names,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$change_capability_commands, avc$cap_cmd_table_field_name,
          avc$change_capability_command, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_capability_commands, avc$cap_cmd_table_field_name,
          avc$display_field_value, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    sort_record_utility_information (record_utility_information, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    avp$create_description_record (avc$user_record_name, utility_information, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Build Account description record.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('INITIALIZE_VALIDATION_RECORDS', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    record_utility_info_header^.number_of_entries := 0;
    record_utility_info_header^.number_of_commands := 0;

    add_new_record_utility_info_cmd (avc$end_change_acct_commands, osc$null_name, avc$end_subutility_command,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_descr_cmds, osc$null_name,
          avc$display_field_description, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_names_cmds, osc$null_name, avc$display_field_names,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$change_capability_commands, avc$cap_cmd_table_field_name,
          avc$change_capability_command, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_capability_commands, avc$cap_cmd_table_field_name,
          avc$display_field_value, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    sort_record_utility_information (record_utility_information, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    avp$create_description_record (avc$account_record_name, utility_information, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Build Account Member description record.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('INITIALIZE_VALIDATION_RECORDS', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    record_utility_info_header^.number_of_commands := 0;
    record_utility_info_header^.number_of_entries := 0;

    add_new_record_utility_info_cmd (avc$end_change_acct_mem_cmds, osc$null_name, avc$end_subutility_command,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_descr_cmds, osc$null_name,
          avc$display_field_description, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_names_cmds, osc$null_name, avc$display_field_names,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$change_capability_commands, avc$cap_cmd_table_field_name,
          avc$change_capability_command, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_capability_commands, avc$cap_cmd_table_field_name,
          avc$display_field_value, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    sort_record_utility_information (record_utility_information, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    avp$create_description_record (avc$account_member_record_name, utility_information, file_information,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Build Project description record.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('INITIALIZE_VALIDATION_RECORDS', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    record_utility_info_header^.number_of_commands := 0;
    record_utility_info_header^.number_of_entries := 0;

    add_new_record_utility_info_cmd (avc$end_change_proj_commands, osc$null_name, avc$end_subutility_command,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_descr_cmds, osc$null_name,
          avc$display_field_description, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_names_cmds, osc$null_name, avc$display_field_names,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$change_capability_commands, avc$cap_cmd_table_field_name,
          avc$change_capability_command, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_capability_commands, avc$cap_cmd_table_field_name,
          avc$display_field_value, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    sort_record_utility_information (record_utility_information, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    avp$create_description_record (avc$project_record_name, utility_information, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

{ Build Project Member description record.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('INITIALIZE_VALIDATION_RECORDS', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    record_utility_info_header^.number_of_commands := 0;
    record_utility_info_header^.number_of_entries := 0;

    add_new_record_utility_info_cmd (avc$end_change_proj_mem_cmds, osc$null_name, avc$end_subutility_command,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_descr_cmds, osc$null_name,
          avc$display_field_description, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_field_names_cmds, osc$null_name, avc$display_field_names,
          record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$change_capability_commands, avc$cap_cmd_table_field_name,
          avc$change_capability_command, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    add_new_record_utility_info_cmd (avc$display_capability_commands, avc$cap_cmd_table_field_name,
          avc$display_field_value, record_utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    sort_record_utility_information (record_utility_information, utility_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    avp$create_description_record (avc$project_member_record_name, utility_information, file_information,
          status);

  PROCEND initialize_validation_records;
?? TITLE := '    prevalidate_job', EJECT ??
  PROCEDURE prevalidate_job
    (    validation_level: avt$validation_level;
         user_name: ost$user_name;
         family_name: ost$family_name;
         validation_attributes: ^avt$validation_items;
         default_attributes: ^avt$validation_items;
     VAR status: ost$status);

    TYPE
      limit_item = record
        limit_name: ost$name,
        user_specified: boolean,
        job_maximum_limit: sft$counter,
        forward: ^limit_item,
      recend;

    VAR
      account_exists: boolean,
      account_name: avt$account_name,
      account_member_exists: boolean,
      audit_information: sft$audit_information,
      caller_authority: avt$validation_authority,
      current_date_time: ost$date_time,
      current_limit_item: ^limit_item,
      data_record: ^avt$template_file_record,
      data_record_size: 0 .. avc$max_template_record_size,
      default_value: avt$field_value,
      description_record: ^avt$template_file_record,
      description_record_name: ost$name,
      description_record_size: 0 .. avc$max_template_record_size,
      descriptive_text: ^avt$descriptive_text,
      default_name: jmt$job_class_name,
      field_count: avt$field_count,
      field_value: avt$field_value,
      field_value_list: avt$field_value_list,
      file_information: avt$template_file_information,
      found_job_class: boolean,
      ignore_status: ost$status,
      increment: pmt$time_increment,
      index: integer,
      item_index: integer,
      job_class: jmt$job_class,
      job_maximum: sft$counter,
      key: avt$validation_key,
      limit_field_names: ^array [1 .. * ] of ost$name,
      limit_item_list: ^limit_item,
      local_limit_name: ost$name,
      local_status: ost$status,
      login_password: avt$login_password,
      project_exists: boolean,
      project_member_exists: boolean,
      project_name: avt$project_name,
      temp_password: avt$password,
      terminal_name_p: ^ift$terminal_name,
      type_specification: avt$type_specification,
      unix_username: string (15),
      utility_information: ^avt$utility_information,
      valid_member: boolean;

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

{ PURPOSE:
{   This is a block exit condition handler that is used to insure that a
{   template file lock set is released if an error occurs.

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

      VAR
        ignore_status: ost$status;

      avp$unlock_template_file (file_information, ignore_status);

    PROCEND condition_handler;
?? OLDTITLE ??
?? NEWTITLE := '      emit_invalid_access_statistic', EJECT ??
{ PURPOSE
{   This procedure is used to emit a statistic to record a possible security violation.

    PROCEDURE emit_invalid_access_statistic
      (    family_name: ost$family_name,
           user_name: ost$user_name;
           terminal_name_p: ^ift$terminal_name);

      VAR
        ignore_status: ost$status,
        statistic_descriptive_data: ost$string;

      statistic_descriptive_data.value := family_name;
      statistic_descriptive_data.size := clp$trimmed_string_size (statistic_descriptive_data.value);

      statistic_descriptive_data.value (statistic_descriptive_data.size + 1, 2) := ', ';
      statistic_descriptive_data.size := statistic_descriptive_data.size + 2;

      statistic_descriptive_data.value (statistic_descriptive_data.size + 1,
            clp$trimmed_string_size (user_name)) := user_name (1, clp$trimmed_string_size (user_name));
      statistic_descriptive_data.size := statistic_descriptive_data.size +
            clp$trimmed_string_size (user_name);

      statistic_descriptive_data.value (statistic_descriptive_data.size + 1, 2) := ', ';
      statistic_descriptive_data.size := statistic_descriptive_data.size + 2;

      IF terminal_name_p <> NIL THEN
        statistic_descriptive_data.value (statistic_descriptive_data.size + 1,
              clp$trimmed_string_size (terminal_name_p^)) := terminal_name_p^ (1, clp$trimmed_string_size
              (terminal_name_p^));
        statistic_descriptive_data.size := statistic_descriptive_data.size +
              clp$trimmed_string_size (terminal_name_p^);
      IFEND;

      sfp$emit_statistic (avc$invalid_access_error, statistic_descriptive_data.
            value (1, statistic_descriptive_data.size), NIL, ignore_status);

    PROCEND emit_invalid_access_statistic;
?? OLDTITLE, EJECT ??
    limit_item_list := NIL;
    account_name := osc$null_name;
    project_name := osc$null_name;
    terminal_name_p := NIL;

{ Get the terminal name from the validation attributes (if it was specified).

    IF validation_attributes <> NIL THEN
    / get_terminal_name /
      FOR item_index := 1 TO UPPERBOUND (validation_attributes^) DO
        IF validation_attributes^ [item_index].key = avc$terminal_name THEN
          terminal_name_p := ^validation_attributes^ [item_index].terminal_name;
          EXIT /get_terminal_name/;
        IFEND;
      FOREND /get_terminal_name/;
    IFEND;

{ Open the validation file.

    avp$open_system_validation_file (family_name, file_information, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /prevalidate/
    BEGIN

{ Push a work area to hold the user data and description record.

      PUSH data_record: [[REP avc$max_template_record_size OF cell]];
      RESET data_record;
      PUSH description_record: [[REP avc$max_template_record_size OF cell]];
      RESET description_record;

{ Read the user information.

      key.account_name := avc$high_value_name;
      key.project_name := avc$high_value_name;
      key.user_name := user_name;
      osp$establish_block_exit_hndlr (^condition_handler);
      avp$read_data_record (key.value, avc$update_access, FALSE, data_record, data_record_size,
            description_record, description_record_size, description_record_name, field_count,
            file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN

{ Set the status we want to exit with.

          osp$set_status_condition (ave$bad_user_validation_info, status);
          emit_invalid_access_statistic (family_name, user_name, terminal_name_p);
        IFEND;
        EXIT /prevalidate/;
      IFEND;

{ Get the login password field value.

      avp$get_field (avc$login_password, data_record, description_record, {work_area=} NIL, field_value,
            type_specification, default_value, descriptive_text, utility_information, status);
      IF NOT status.normal THEN
        EXIT /prevalidate/;
      IFEND;

{ Check the login password for expiration.

      IF field_value.login_password_exp_date^.year <> avc$no_expiration_date THEN
        pmp$get_compact_date_time (current_date_time, status);
        IF NOT status.normal THEN
          EXIT /prevalidate/;
        IFEND;
        pmp$compute_date_time_increment (current_date_time, field_value.login_password_exp_date^, increment,
              status);
        IF NOT status.normal THEN
          EXIT /prevalidate/;
        IFEND;
        IF (increment.year < 0) OR (increment.month < 0) OR (increment.day < 0) OR (increment.hour < 0) OR
              (increment.minute < 0) OR (increment.second < 0) OR (increment.millisecond < 0) THEN

{ Set the status we want to exit with.

          osp$set_status_condition (ave$bad_user_validation_info, status);
          emit_invalid_access_statistic (family_name, user_name, terminal_name_p);
          EXIT /prevalidate/;
        IFEND;
      IFEND;

{ Validate the requested items.

      IF validation_attributes <> NIL THEN
        FOR item_index := 1 TO UPPERBOUND (validation_attributes^) DO
          CASE validation_attributes^ [item_index].key OF

{ Validate the specified account and project.

          = avc$account_project_key =

            account_name := validation_attributes^ [item_index].account_name;
            project_name := validation_attributes^ [item_index].project_name;

{ Get the user's default account and project if blanks were specified.

            IF ((account_name = osc$null_name) OR (project_name = osc$null_name)) THEN
              avp$get_field (avc$default_account_project, data_record, description_record, {work_area=} NIL,
                    field_value, type_specification, default_value, descriptive_text, utility_information,
                    status);
              IF NOT status.normal THEN
                EXIT /prevalidate/;
              IFEND;
              IF account_name = osc$null_name THEN
                account_name := field_value.account_name^;
              IFEND;
              IF project_name = osc$null_name THEN
                project_name := field_value.project_name^;
              IFEND;
            IFEND;

{ Verify that the user is a valid member.

            verify_acct_proj_membership (validation_level, account_name, project_name, user_name,
                  account_exists, project_exists, valid_member, file_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

            IF NOT valid_member THEN
              IF NOT account_exists THEN
                osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
              ELSEIF NOT project_exists THEN
                osp$set_status_abnormal ('AV', ave$project_does_not_exist, project_name, status);
                osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
              ELSEIF validation_level = avc$account_level THEN
                  osp$set_status_abnormal ('AV', ave$acct_member_does_not_exist, user_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
              ELSE
                  osp$set_status_abnormal ('AV', ave$member_does_not_exist, user_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, project_name, status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
              IFEND;
              EXIT /prevalidate/;
            IFEND;

{ Validate the specified job class.

          = avc$job_class_name_key =

{ Retrieve the user's valid job class list.

            avp$get_field (avc$job_class, data_record, description_record, {work_area=} NIL , field_value,
                  type_specification, default_value, descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

{ Verify that the user is valid for the requested job class.

            validate_job_class (field_value, validation_attributes^ [item_index].job_class_name,
                  found_job_class);
            IF NOT found_job_class THEN
              osp$set_status_abnormal ('AV', ave$bad_job_class,
                    validation_attributes^ [item_index].job_class_name, status);
              EXIT /prevalidate/;
            IFEND;

{ Validate the specified job execution ring.

          = avc$job_execution_ring_key =

{ Retrieve the user's ring privileges.

            avp$get_field (avc$ring_privileges, data_record, description_record, {work_area=} NIL,
                  field_value, type_specification, default_value, descriptive_text, utility_information,
                  status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

{ Verify that the user is valid to run at the specified ring.

            IF validation_attributes^ [item_index].job_execution_ring < field_value.minimum_ring^ THEN
              osp$set_status_abnormal ('AV', ave$bad_ring, '', status);
              EXIT /prevalidate/;
            IFEND;

{ Validate the specified job limit.

          = avc$job_limit_key =

{ Save the specified job limit for later validation.

            IF limit_item_list = NIL THEN
              PUSH current_limit_item;
              limit_item_list := current_limit_item;
            ELSE
              PUSH current_limit_item^.forward;
              current_limit_item := current_limit_item^.forward;
            IFEND;
            current_limit_item^.limit_name := validation_attributes^ [item_index].limit_name;
            current_limit_item^.user_specified := validation_attributes^ [item_index].user_specified;
            current_limit_item^.job_maximum_limit := validation_attributes^ [item_index].job_maximum;
            current_limit_item^.forward := NIL;

{ Validate the specified password.

          = avc$password_key =

{ Don't allow login to the $SYSTEM user.

            IF user_name = jmc$system_user THEN

{ Set the status we want to exit with.

              osp$set_status_condition (ave$bad_user_validation_info, status);
              emit_invalid_access_statistic (family_name, user_name, terminal_name_p);
              EXIT /prevalidate/;
            IFEND;

{ Retrieve the user's login password value.

            avp$get_field (avc$login_password, data_record, description_record, {work_area=} NIL, field_value,
                  type_specification, default_value, descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

{ Encrypt the specified login password value.

            login_password.encrypted := TRUE;
            avp$encrypt_password (user_name, validation_attributes^ [item_index].password,
                  login_password.value, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

{ Verify the specfied login password value.

            IF field_value.login_password^.value <> login_password.value THEN
              temp_password := login_password.value;
              avp$old_encrypt_password (user_name, validation_attributes^ [item_index].password,
                    login_password.value, status);
              IF NOT status.normal THEN
                EXIT /prevalidate/;
              IFEND;
              IF field_value.login_password^.value <> login_password.value THEN

{ Set the status we want to exit with.

                osp$set_status_condition (ave$bad_user_validation_info, status);
                emit_invalid_access_statistic (family_name, user_name, terminal_name_p);
                avp$get_field (avc$invalid_login_attempts, data_record, description_record,
                      { work_area = } NIL, field_value, type_specification, default_value, descriptive_text,
                      utility_information, local_status);
                IF NOT local_status.normal THEN
                  EXIT /prevalidate/;
                IFEND;
                IF (type_specification.kind = avc$accumulating_limit_kind) THEN
                  PUSH field_value_list;
                  field_value_list^.forward := NIL;
                  field_value_list^.field_name := avc$invalid_login_attempts;
                  field_value_list^.field_value := field_value;
                  field_value_list^.field_value.total_accumulation^ := field_value.total_accumulation^ + 1;
                  avp$rewrite_data_record (key.value, { automatically_unlock = } TRUE, data_record,
                        description_record, field_value_list, file_information, ignore_status);
                IFEND;
                EXIT /prevalidate/;
              ELSE

{ Save the current password value encrypted with the current algorithm on the validation file.

                PUSH field_value_list;
                field_value_list^.forward := NIL;
                field_value_list^.field_name := avc$login_password;
                field_value_list^.field_value := field_value;
                field_value_list^.field_value.login_password^.value := temp_password;
                avp$rewrite_data_record (key.value, { automatically_unlock = } FALSE, data_record,
                      description_record, field_value_list, file_information, status);
                IF NOT status.normal THEN
                  EXIT /prevalidate/;
                IFEND;
              IFEND;
            IFEND;

{ Validate the specified required capability.

          = avc$required_capability_key =

{ Retrieve the specified capability.

            avp$get_field (validation_attributes^ [item_index].required_capability, data_record,
                  description_record, {work_area=} NIL, field_value, type_specification, default_value,
                  descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

{ Verify that the user has the specified required capability.

            IF NOT field_value.capability^ THEN
              osp$set_status_abnormal ('AV', ave$missing_required_capability,
                    validation_attributes^ [item_index].required_capability, status);
              EXIT /prevalidate/;
            IFEND;

{ Verify the unix username matches.

          = avc$unix_username_key =
            avp$get_field (avc$unix_user_name, data_record, description_record, {work_area=} NIL, field_value,
                  type_specification, default_value, descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

            IF field_value.kind <> avc$string_kind THEN
              osp$set_status_abnormal ('AV', ave$incorrect_kind, avc$unix_user_name, status);
              EXIT /prevalidate/;
            IFEND;

            #TRANSLATE (osv$upper_to_lower, field_value.string_value^, unix_username);
            IF unix_username = '$translate' THEN
              #TRANSLATE (osv$upper_to_lower, user_name, unix_username);
            ELSE
              unix_username := field_value.string_value^;
            IFEND;
            IF validation_attributes^ [item_index].unix_username <> unix_username THEN
              osp$set_status_condition (ave$bad_user_validation_info, status);
              EXIT /prevalidate/;
            IFEND;

          = avc$terminal_name =
            terminal_name_p := ^validation_attributes^ [item_index].terminal_name;
          ELSE
            ;
          CASEND;
        FOREND;
      IFEND;

{ Limit Checking

{ Retrieve a list of all accumulating limit and limit type fields from the user record.

      PUSH limit_field_names: [1 .. avc$maximum_field_count];
      avp$get_field_names ($avt$field_kind_set [avc$accumulating_limit_kind, avc$limit_kind], FALSE,
            description_record, limit_field_names^, field_count, status);
      IF NOT status.normal THEN
        EXIT /prevalidate/;
      IFEND;

{ Check each user limit.

      FOR index := 1 TO field_count DO
        avp$get_field (limit_field_names^ [index], data_record, description_record, {work_area=} NIL,
              field_value, type_specification, default_value, descriptive_text, utility_information, status);
        IF NOT status.normal THEN
          EXIT /prevalidate/;
        IFEND;

{ Verify that the total limit has not been exceeded.

        IF ((type_specification.kind = avc$accumulating_limit_kind) AND
              (type_specification.total_limit_applies^) AND (type_specification.total_limit_stops_login^) AND
              (field_value.total_limit^ <> sfc$unlimited) AND (field_value.total_accumulation^ >=
              field_value.total_limit^)) THEN
          osp$set_status_condition (ave$bad_user_validation_info, status);
          EXIT /prevalidate/;
        IFEND;

{ Determine the job maximum limit.

        IF (((type_specification.kind = avc$limit_kind) AND (field_value.limit_value^ <> sfc$unlimited)) OR
              ((type_specification.kind = avc$accumulating_limit_kind) AND
              (type_specification.job_limits_apply^) AND (field_value.job_maximum_limit^ <> sfc$unlimited)))
              THEN
          IF (type_specification.kind = avc$accumulating_limit_kind) THEN
            job_maximum := field_value.job_maximum_limit^;
            IF ((type_specification.total_limit_applies^) AND
                  (type_specification.total_limit_stops_login^) AND
                  (field_value.total_limit^ <> sfc$unlimited)) THEN
              IF ((field_value.total_limit^) - (field_value.total_accumulation^)) < job_maximum THEN
                job_maximum := ((field_value.total_limit^) - (field_value.total_accumulation^));
              IFEND;
            IFEND;
          ELSE
            job_maximum := field_value.limit_value^;
          IFEND;

          current_limit_item := limit_item_list;

{ Check to see if the user has specified a job maximum for this limit.

        /find_specified_job_maximum/
          WHILE current_limit_item <> NIL DO

{ The user may not specify a job maximum that is greater than he is validated for.

            local_limit_name := type_specification.limit_name^;
            IF local_limit_name = avc$cp_time_limit_name THEN
              local_limit_name := avc$cpu_time_limit_name;
            IFEND;
            IF current_limit_item^.limit_name = local_limit_name THEN
              IF ((current_limit_item^.user_specified) AND (job_maximum <
                    current_limit_item^.job_maximum_limit)) THEN
                osp$set_status_abnormal ('AV', ave$bad_user_specified_job_max, local_limit_name,  status);
                EXIT /prevalidate/;

{ If the job maximum specified is less than current reset it.

              ELSEIF job_maximum < current_limit_item^.job_maximum_limit THEN
                current_limit_item^.job_maximum_limit := job_maximum;
              IFEND;
              EXIT /find_specified_job_maximum/;
            ELSE
              current_limit_item := current_limit_item^.forward;
            IFEND;
          WHILEND /find_specified_job_maximum/;

{ If the user did not specify a job maximum for this limit then create an entry
{ in the job limit chain so that the job maximum limit can be found for return
{ to the caller if requested.

          IF current_limit_item = NIL THEN
            PUSH current_limit_item;
            current_limit_item^.limit_name := type_specification.limit_name^;
            IF current_limit_item^.limit_name = avc$cp_time_limit_name THEN
              current_limit_item^.limit_name := avc$cpu_time_limit_name;
            IFEND;
            current_limit_item^.user_specified := FALSE;
            current_limit_item^.job_maximum_limit := job_maximum;
            current_limit_item^.forward := limit_item_list;
            limit_item_list := current_limit_item;
          IFEND;
        IFEND;
      FOREND;

{ Retrieve requested validation items for return to caller.

      IF default_attributes <> NIL THEN
        FOR item_index := 1 TO UPPERBOUND (default_attributes^) DO
          CASE default_attributes^ [item_index].key OF

{ Return the requested default batch and interactive job class for the user.

          = avc$job_class_defaults_key =

{ Retrieve the user's job class validation values.

            avp$get_field (avc$job_class, data_record, description_record, {work_area=} NIL, field_value,
                  type_specification, default_value, descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;
            default_attributes^ [item_index].batch_job_class_default := field_value.batch_job_class_default^;
            default_attributes^ [item_index].interactive_job_class_default :=
                  field_value.interactive_job_class_default^;

{ Return the requested limit values for the user.

          = avc$job_limit_key =

{ Search the previously built job limit chain for the limit value to return.

            current_limit_item := limit_item_list;

          /find_limit_to_return/
            WHILE current_limit_item <> NIL DO

              IF current_limit_item^.limit_name = default_attributes^ [item_index].limit_name THEN
                default_attributes^ [item_index].user_specified := current_limit_item^.user_specified;
                default_attributes^ [item_index].job_maximum := current_limit_item^.job_maximum_limit;
                EXIT /find_limit_to_return/;
              ELSE
                current_limit_item := current_limit_item^.forward;
              IFEND;
            WHILEND /find_limit_to_return/;
            IF current_limit_item = NIL THEN
              default_attributes^ [item_index].user_specified := FALSE;
              default_attributes^ [item_index].job_maximum := sfc$unlimited;
            IFEND;

{ Return the requested labeled names value for the user.

          = avc$labeled_names_key =

            avp$get_field (default_attributes^ [item_index].labeled_names_field, data_record,
                  description_record, default_attributes^ [item_index].work_area, field_value,
                  type_specification, default_value, descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;
            default_attributes^ [item_index].labeled_names := field_value.labeled_names;

{ Return the requested capability value for the user.

          = avc$optional_capability_key =

{ If the user has the requested capability then the capability name is returned.
{ If the user does not have the requested capability then a null capability name is returned.

            avp$get_field (default_attributes^ [item_index].optional_capability, data_record,
                  description_record, {work_area=} NIL, field_value, type_specification, default_value,
                  descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;
            IF field_value.capability^ <> TRUE THEN
              default_attributes^ [item_index].optional_capability := osc$null_name;
            IFEND;

{ Return the requested encrypted password value for the user.

          = avc$password_key =

{ Retrieve the encrypted login password value for the user.

            avp$get_field (avc$login_password, data_record, description_record, {work_area=} NIL, field_value,
                  type_specification, default_value, descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;
            default_attributes^ [item_index].password := field_value.login_password^.value;

{ Return the requested list of valid job classes for the user.

          = avc$valid_job_classes_key =

{ Retrieve the valid job classes for the user.

            avp$get_field (avc$job_class, data_record, description_record, {work_area=} NIL, field_value,
                  type_specification, default_value, descriptive_text, utility_information, status);
            IF NOT status.normal THEN
              EXIT /prevalidate/;
            IFEND;

{ Copy as many entries from the list of valid job classes to the specified
{ array that will fit.  The count of job classes is always the number that
{ exists on the validation file not the number that was returned.

          /process_valid_job_classes/
            FOR index := 1 TO UPPERBOUND (field_value.job_classes^) DO
              IF index <= UPPERBOUND (default_attributes^ [item_index].job_classes^) THEN
                default_attributes^ [item_index].job_classes^ [index] := field_value.job_classes^ [index];
              ELSE
                EXIT /process_valid_job_classes/;
              IFEND;
            FOREND /process_valid_job_classes/;
            default_attributes^ [item_index].count := UPPERBOUND (field_value.job_classes^);

          ELSE
            ;
          CASEND;
        FOREND;
      IFEND;

    END /prevalidate/;
    avp$unlock_template_file (file_information, ignore_status);
    osp$disestablish_cond_handler;

{ Emit the audit statistic.

    IF avp$security_option_active (avc$vso_security_audit) THEN
      audit_information.audited_operation := sfc$ao_val_prevalidate_user;
      audit_information.prevalidate_user.family_name_p := ^family_name;
      audit_information.prevalidate_user.user_name_p := ^user_name;
      audit_information.prevalidate_user.account_name_p := ^account_name;
      audit_information.prevalidate_user.project_name_p := ^project_name;
      audit_information.prevalidate_user.terminal_name_p := terminal_name_p;
      sfp$emit_audit_statistic (audit_information, status);
    IFEND;

    avp$close_template_file (file_information, ignore_status);

  PROCEND prevalidate_job;
?? TITLE := '    read_account_member_record', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the create, change, and display account member
{ record interfaces to store an account member record for later processing
{ by those interfaces.
{

  PROCEDURE read_account_member_record
    (    caller_id: ost$caller_identifier;
     VAR account_name: avt$account_name;
     VAR user_name: ost$user_name;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      ignore_status: ost$status,
      key: avt$validation_key;

    status.normal := TRUE;

    validation_record_info := NIL;

{ If the user name specified is a blank name then seqentially access the next
{ account member record.

    IF user_name <> osc$null_name THEN
      key.account_name := account_name;
      key.project_name := osc$null_name;
      key.user_name := user_name;
    ELSE
      key.value := ' ';
    IFEND;

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);

  /read_account_member/
    BEGIN
      read_validation_record (avc$account_member_record_name, key, validation_record_info, file_information,
            status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          IF caller_authority < avc$account_admin_authority THEN
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          ELSE
            osp$set_status_abnormal ('AV', ave$acct_member_does_not_exist, user_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
          IFEND;
        IFEND;
        EXIT /read_account_member/;
      IFEND;
      account_name := key.account_name;
      user_name := key.user_name;
      validation_record_info^.caller_authority := caller_authority;

{ Verify that the caller has the required authority.

      IF caller_authority < avc$account_admin_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /read_account_member/;
      IFEND;

    END /read_account_member/;

    IF (NOT status.normal) AND (validation_record_info <> NIL) THEN
      avp$release_record_id (validation_record_info^.record_id, ignore_status);
    IFEND;

  PROCEND read_account_member_record;
?? TITLE := '    read_account_record', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the create, change, and display account
{ record interfaces to store an account record for later processing
{ by those interfaces.
{

  PROCEDURE read_account_record
    (    caller_id: ost$caller_identifier;
     VAR account_name: avt$account_name;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      ignore_status: ost$status,
      key: avt$validation_key;

    status.normal := TRUE;

    validation_record_info := NIL;

{ If the account name specified is a blank name then seqentially access the next
{ account record.

    IF account_name <> osc$null_name THEN
      key.account_name := account_name;
      key.project_name := osc$null_name;
      key.user_name := osc$null_name;
    ELSE
      key.value := ' ';
    IFEND;

    determine_caller_authority (caller_id, ^account_name, NIL, NIL, NIL, NIL, caller_authority);

  /read_account/
    BEGIN
      read_validation_record (avc$account_record_name, key, validation_record_info, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          IF caller_authority < avc$account_admin_authority THEN
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          ELSE
            osp$set_status_abnormal ('AV', ave$account_does_not_exist, account_name, status);
          IFEND;
        IFEND;
        EXIT /read_account/;
      IFEND;
      account_name := key.account_name;
      validation_record_info^.caller_authority := caller_authority;

{ Verify that the caller has the required authority.

      IF caller_authority < avc$account_admin_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /read_account/;
      IFEND;

    END /read_account/;

    IF (NOT status.normal) AND (validation_record_info <> NIL) THEN
      avp$release_record_id (validation_record_info^.record_id, ignore_status);
    IFEND;

  PROCEND read_account_record;
?? TITLE := '    read_project_member_record', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the create, change, and display project member
{ record interfaces to store a project member record for later processing
{ by those interfaces.
{

  PROCEDURE read_project_member_record
    (    caller_id: ost$caller_identifier;
     VAR account_name: avt$account_name;
     VAR project_name: avt$project_name;
     VAR user_name: ost$user_name;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      ignore_status: ost$status,
      key: avt$validation_key;

    status.normal := TRUE;

    validation_record_info := NIL;

{ If the user name specified is a blank name then seqentially access the next
{ project member record.

    IF user_name <> osc$null_name THEN
      key.account_name := account_name;
      key.project_name := project_name;
      key.user_name := user_name;
    ELSE
      key.value := ' ';
    IFEND;

    determine_caller_authority (caller_id, ^account_name, ^project_name, NIL, NIL, NIL, caller_authority);

  /read_project_member/
    BEGIN
      read_validation_record (avc$project_member_record_name, key, validation_record_info, file_information,
            status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          IF caller_authority < avc$project_admin_authority THEN
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          ELSE
            osp$set_status_abnormal ('AV', ave$proj_member_does_not_exist, user_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, project_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
          IFEND;
        IFEND;
        EXIT /read_project_member/;
      IFEND;
      account_name := key.account_name;
      project_name := key.project_name;
      user_name := key.user_name;
      validation_record_info^.caller_authority := caller_authority;

{ Verify that the caller has the required authority.

      IF caller_authority < avc$project_admin_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /read_project_member/;
      IFEND;

    END /read_project_member/;

    IF (NOT status.normal) AND (validation_record_info <> NIL) THEN
      avp$release_record_id (validation_record_info^.record_id, ignore_status);
    IFEND;

  PROCEND read_project_member_record;
?? TITLE := '    read_project_record', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the create, change, and display project
{ record interfaces to store a project record for later processing
{ by those interfaces.
{

  PROCEDURE read_project_record
    (    caller_id: ost$caller_identifier;
     VAR account_name: avt$account_name;
     VAR project_name: avt$project_name;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      caller_authority: avt$validation_authority,
      ignore_status: ost$status,
      key: avt$validation_key;

    status.normal := TRUE;

    validation_record_info := NIL;

{ If the project name specified is a blank name then seqentially access the next
{ project record.

    IF project_name <> osc$null_name THEN
      key.account_name := account_name;
      key.project_name := project_name;
      key.user_name := osc$null_name;
    ELSE
      key.value := ' ';
    IFEND;

    determine_caller_authority (caller_id, ^account_name, ^project_name, NIL, NIL, NIL, caller_authority);

  /read_project/
    BEGIN
      read_validation_record (avc$project_record_name, key, validation_record_info, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          IF caller_authority < avc$project_admin_authority THEN
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          ELSE
            osp$set_status_abnormal ('AV', ave$project_does_not_exist, project_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, account_name, status);
          IFEND;
        IFEND;
        EXIT /read_project/;
      IFEND;
      account_name := key.account_name;
      project_name := key.project_name;
      validation_record_info^.caller_authority := caller_authority;

{ Verify that the caller has the required authority.

      IF caller_authority < avc$project_admin_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /read_project/;
      IFEND;

    END /read_project/;

    IF (NOT status.normal) AND (validation_record_info <> NIL) THEN
      avp$release_record_id (validation_record_info^.record_id, ignore_status);
    IFEND;

  PROCEND read_project_record;
?? TITLE := '    read_user_record', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the create, change, and display project
{ record interfaces to read a user record and store it for processing
{ by those interfaces.
{

  PROCEDURE read_user_record
    (    caller_id: ost$caller_identifier;
     VAR user_name: ost$user_name;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      default_value: avt$field_value,
      descriptive_text: ^avt$descriptive_text,
      field_value: avt$field_value,
      ignore_status: ost$status,
      key: avt$validation_key,
      type_specification: avt$type_specification,
      user_identification: ost$user_identification,
      utility_information: ^avt$utility_information;

    status.normal := TRUE;

    validation_record_info := NIL;

{ If the user name specified is a blank name then seqentially access the next
{ user record.

    IF user_name <> osc$null_name THEN
      key.account_name := avc$high_value_name;
      key.project_name := avc$high_value_name;
      key.user_name := user_name;
    ELSE
      key.value := ' ';
    IFEND;

  /read_user/
    BEGIN
      read_validation_record (avc$user_record_name, key, validation_record_info, file_information, status);
      IF NOT status.normal THEN
        IF status.condition = ave$unknown_record THEN
          IF avp$system_administrator () OR avp$family_administrator () THEN
            osp$set_status_abnormal ('AV', ave$user_does_not_exist, user_name, status);
          ELSE
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
          IFEND;
        IFEND;
        EXIT /read_user/;
      IFEND;
      user_name := key.user_name;

      avp$get_field (avc$creation_account_project, validation_record_info^.data_record,
            validation_record_info^.description_record, validation_record_info^.work_area.sequence_pointer,
            field_value, type_specification, default_value, descriptive_text, utility_information, status);
      IF NOT status.normal THEN
        EXIT /read_user/;
      IFEND;

{ Verify that the caller has the required authority.

      determine_caller_authority (caller_id, NIL, NIL, ^key.user_name, field_value.account_name,
            field_value.project_name, validation_record_info^.caller_authority);
      IF validation_record_info^.caller_authority < avc$user_authority THEN
        osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
        EXIT /read_user/;
      IFEND;

      IF validation_record_info^.caller_authority < avc$system_admin_authority THEN
        pmp$get_user_identification (user_identification, status);
        IF NOT status.normal THEN
          EXIT /read_user/;
        IFEND;

{ If the user is not reading his own user validation record, make sure he is not reading someone with more
{ authority.

        IF user_identification.user <> key.user_name THEN
          avp$get_field (avc$system_administration, validation_record_info^.data_record,
              validation_record_info^.description_record, validation_record_info^.work_area.sequence_pointer,
              field_value, type_specification, default_value, descriptive_text, utility_information, status);
          IF NOT status.normal THEN
            EXIT /read_user/;
          IFEND;

          IF field_value.capability^ THEN
            osp$set_status_abnormal ('AV', ave$insufficient_authority, '', status);
            EXIT /read_user/;
          IFEND;
        IFEND;
      IFEND;

    END /read_user/;

    IF (NOT status.normal) AND (validation_record_info <> NIL) THEN
      avp$release_record_id (validation_record_info^.record_id, ignore_status);
    IFEND;

  PROCEND read_user_record;
?? TITLE := '    read_validation_record', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used by the previous read record procedures to
{ perform common routines needed to store a validation record for
{ later access by separate validation interfaces.
{

  PROCEDURE read_validation_record
    (    validation_record_name: ost$name;
     VAR key: avt$validation_key;
     VAR validation_record_info: ^avt$validation_record_info;
     VAR file_information: avt$template_file_information;
     VAR status: ost$status);

    VAR
      data_record: ^avt$template_file_record,
      data_record_size: 0 .. avc$max_template_record_size,
      description_record: ^avt$template_file_record,
      description_record_size: 0 .. avc$max_template_record_size,
      description_record_name: ost$name,
      field_count: avt$field_count,
      ignore_status: ost$status,
      temp_data_record: ^avt$template_file_record,
      temp_description_record: ^avt$template_file_record;

    status.normal := TRUE;
    description_record := NIL;
    data_record := NIL;
    validation_record_info := NIL;

{ Allocate a work area to hold the a maximum sized data and description record.

    PUSH temp_data_record: [[REP avc$max_template_record_size OF cell]];
    RESET temp_data_record;
    PUSH temp_description_record: [[REP avc$max_template_record_size OF cell]];
    RESET temp_description_record;

  /read_record/
    BEGIN
      IF key.value <> ' ' THEN

{ Read the specified validation record.

        avp$read_data_record (key.value, avc$read_access, TRUE, temp_data_record, data_record_size,
              temp_description_record, description_record_size, description_record_name, field_count,
              file_information, status);
        IF NOT status.normal THEN
          EXIT /read_record/;
        IFEND;

      ELSE

{ If a null key is specified sequentially read the next validation record,
{ of the type requested.

        REPEAT
          RESET temp_data_record;
          RESET temp_description_record;
          avp$read_next_data_record (avc$read_access, TRUE, key.value, temp_data_record,
                temp_description_record, description_record_name, field_count, file_information, status);
        UNTIL (NOT status.normal) OR (description_record_name = validation_record_name);
        IF NOT status.normal THEN
          EXIT /read_record/;
        IFEND;
      IFEND;

{ Allocate space to hold the validation record read.

      data_record_size := i#current_sequence_position (temp_data_record);
      description_record_size := i#current_sequence_position (temp_description_record);
      ALLOCATE data_record: [[REP data_record_size OF cell]] IN osv$task_private_heap^;
      RESET data_record;
      ALLOCATE description_record: [[REP description_record_size OF cell]] IN osv$task_private_heap^;
      RESET description_record;
      i#move (temp_data_record, data_record, data_record_size);
      i#move (temp_description_record, description_record, description_record_size);

{ Allocate a new validation record information entry in task private.

      ALLOCATE validation_record_info IN osv$task_private_heap^;

{ Assign a record identifier for the validation record information entry.

      pmp$get_unique_name (validation_record_info^.record_id, status);
      IF NOT status.normal THEN
        EXIT /read_record/;
      IFEND;

{ Initialize the validation record information entry.

      validation_record_info^.work_area.sequence_pointer := NIL;
      validation_record_info^.key := key;
      validation_record_info^.description_record_name := description_record_name;
      validation_record_info^.data_record := data_record;
      validation_record_info^.description_record := description_record;
      validation_record_info^.caller_authority := avc$any_authority;
      validation_record_info^.field_value_list := NIL;

{ Put the validation record information entry in the front of the chain.

      validation_record_info^.backward := NIL;
      validation_record_info^.forward := avv$validation_record_info;
      IF validation_record_info^.forward <> NIL THEN
        validation_record_info^.forward^.backward := validation_record_info;
      IFEND;
      avv$validation_record_info := validation_record_info;
    END /read_record/;

    IF NOT status.normal THEN
      IF validation_record_info <> NIL THEN
        FREE validation_record_info IN osv$task_private_heap^;
      IFEND;
    IFEND;

  PROCEND read_validation_record;
?? TITLE := '    sort_record_utility_info', EJECT ??
{
{ PURPOSE:
{
{   This procedure sorts the command table information within the record utility
{ information.
{

  PROCEDURE sort_record_utility_information
    (VAR record_utility_information: ^avt$utility_information;
     VAR utility_information: ^avt$utility_information;
     VAR status: ost$status);

    VAR
      index: 1 .. avc$maximum_field_count,
      record_utility_info_header: ^avt$record_utility_info_header,
      record_utility_info_array: ^array [1 .. * ] of avt$record_utility_info_entry,
      swapped_entries: boolean,
      temporary_directory_entry: avt$record_utility_info_entry;

    status.normal := TRUE;

{ Retrieve the header information from the record utility information.

    RESET record_utility_information;
    NEXT record_utility_info_header IN record_utility_information;
    IF record_utility_info_header = NIL THEN
      corrupted_sequence ('SORT_RECORD_UTILITY_INFO', 'HEADER', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;

{ Retrieve the command table information from the record utility information.

    NEXT record_utility_info_array: [1 .. record_utility_info_header^.number_of_entries] IN
          record_utility_information;
    IF record_utility_info_array = NIL THEN
      corrupted_sequence ('SORT_RECORD_UTILITY_INFO', 'COMMAND_TABLE', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;

{ Sort the command table entries.

    REPEAT
      swapped_entries := FALSE;
      FOR index := 1 TO UPPERBOUND (record_utility_info_array^) - 1 DO
        IF record_utility_info_array^ [index].command_table_entry.name >
              record_utility_info_array^ [index + 1].command_table_entry.name THEN
          temporary_directory_entry := record_utility_info_array^ [index];
          record_utility_info_array^ [index] := record_utility_info_array^ [index + 1];
          record_utility_info_array^ [index + 1] := temporary_directory_entry;
          swapped_entries := TRUE;
        ELSEIF record_utility_info_array^ [index].command_table_entry.name =
              record_utility_info_array^ [index + 1].command_table_entry.name THEN
          osp$set_status_abnormal ('AV', ave$cmd_already_in_cmd_table,
                record_utility_info_array^ [index].command_table_entry.name, status);
          osp$append_status_parameter (osc$status_parameter_delimiter,
                record_utility_info_array^ [index].field_name, status);
          RETURN;
        IFEND;
      FOREND;

    UNTIL NOT swapped_entries;

{ Return a pointer to a sequence containing the record utility infomation
{ of the exact size.

    RESET record_utility_information;
    NEXT utility_information: [[REP 1 OF avt$record_utility_info_header,
          REP record_utility_info_header^.number_of_entries OF avt$record_utility_info_entry]] IN
          record_utility_information;
    IF utility_information = NIL THEN
      corrupted_sequence ('SORT_RECORD_UTILITY_INFO', 'UTILITY_INFO', 'RECORD_UTILITY_INFORMATION', status);
      RETURN;
    IFEND;
    RESET utility_information;

  PROCEND sort_record_utility_information;

?? TITLE := '    validate_job_class', EJECT ??
{
{ PURPOSE:
{
{   This procedure is used to verify that a user is valid to access a
{ specified job class.
{

  PROCEDURE validate_job_class
    (    field_value: avt$field_value;
         job_class_name: jmt$job_class_name;
     VAR found_job_class: boolean);

    VAR
      index: integer;

    found_job_class := FALSE;

{ If the list contains NONE then no job classes can be valid.

    IF (field_value.job_classes^ [1] <> 'NONE') THEN

{ If the list contains ALL then any job class will be valid.

      IF field_value.job_classes^ [1] = 'ALL' THEN
        found_job_class := TRUE;
      ELSE

{ Else search for the specified job class.

      /find_job_class/
        FOR index := 1 TO UPPERBOUND (field_value.job_classes^) DO
          IF field_value.job_classes^ [index] = job_class_name THEN
            found_job_class := TRUE;
            EXIT /find_job_class/;
          IFEND;
        FOREND /find_job_class/;
      IFEND;
    IFEND;

  PROCEND validate_job_class;
?? TITLE := '    verify_acct_proj_membership', EJECT ??
    PROCEDURE verify_acct_proj_membership
      (    validation_level: avt$validation_level;
           account: avt$account_name;
           project: avt$project_name;
           user: ost$user_name;
       VAR valid_account: boolean;
       VAR valid_project: boolean;
       VAR valid_member: boolean;
       VAR file_information: avt$template_file_information;
       VAR status: ost$status);

      VAR
        validation_key: avt$validation_key;

      status.normal := TRUE;

      valid_member := TRUE;
      valid_account := TRUE;
      valid_project := TRUE;

      IF validation_level = avc$account_level THEN

{ Check for specific account member record.

        validation_key.account_name := account;
        validation_key.project_name := osc$null_name;
        validation_key.user_name := user;
        avp$determine_if_key_exists (validation_key.value, valid_member, file_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ If not a member of the account, check if the account exists.

        IF NOT valid_member THEN
          validation_key.account_name := account;
          validation_key.project_name := osc$null_name;
          validation_key.user_name := osc$null_name;
          avp$determine_if_key_exists (validation_key.value, valid_account, file_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

{ If the account exists and the user is not a member, check for a public account.

        IF valid_account AND (NOT valid_member) THEN
          validation_key.account_name := account;
          validation_key.project_name := osc$null_name;
          validation_key.user_name := 'PUBLIC';
          avp$determine_if_key_exists (validation_key.value, valid_member, file_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

      ELSEIF validation_level = avc$project_level THEN

{ Check for specific project member record.

        validation_key.account_name := account;
        validation_key.project_name := project;
        validation_key.user_name := user;
        avp$determine_if_key_exists (validation_key.value, valid_member, file_information, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

{ If no specific project member record is found, check if the project exists.

        IF NOT valid_member THEN
          validation_key.account_name := account;
          validation_key.project_name := project;
          validation_key.user_name := osc$null_name;
          avp$determine_if_key_exists (validation_key.value, valid_project, file_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

{ If the project does not exist, check if the account exists.

        IF NOT valid_project THEN
          validation_key.account_name := account;
          validation_key.project_name := osc$null_name;
          validation_key.user_name := osc$null_name;
          avp$determine_if_key_exists (validation_key.value, valid_account, file_information, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        IFEND;

{ If the project exists and the user is not a project member, continue checking.

        IF valid_project AND (NOT valid_member) THEN

{ Check for a specific account member record.

          IF NOT valid_member THEN
            validation_key.account_name := account;
            validation_key.project_name := osc$null_name;
            validation_key.user_name := user;
            avp$determine_if_key_exists (validation_key.value, valid_member, file_information, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;

{ If not a specific account member, check for a public project.

          IF NOT valid_member THEN
            validation_key.account_name := account;
            validation_key.project_name := project;
            validation_key.user_name := 'PUBLIC';
            avp$determine_if_key_exists (validation_key.value, valid_member, file_information, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;

{ If not a public project, check for a public account.

          IF NOT valid_member THEN
            validation_key.account_name := account;
            validation_key.project_name := osc$null_name;
            validation_key.user_name := 'PUBLIC';
            avp$determine_if_key_exists (validation_key.value, valid_member, file_information, status);
            IF NOT status.normal THEN
              RETURN;
            IFEND;
          IFEND;
        IFEND;
      IFEND;

    PROCEND verify_acct_proj_membership;
?? OLDTITLE ??
?? TITLE := '  Validation Interface Miscellaneous Support Routines' ??
  ?IF avc$compile_test_code THEN
?? NEWTITLE := '    initalize', EJECT ??

    PROCEDURE [XDCL] initialize
      (    validation_level: avt$validation_level;
           system_administrator: boolean;
           family_administrator: boolean;
       VAR status: ost$status);

      VAR
        ignore_status: ost$status,
        jp_segment_pointer: amt$segment_pointer,
        task_shared_file_id: amt$file_identifier,
        task_private_file_id: amt$file_identifier,
        tp_segment_pointer: amt$segment_pointer,
        ts_segment_pointer: amt$segment_pointer;

      status.normal := TRUE;


{  Add/delete system_administrator and family_administration validation from the set of validations.

      IF system_administrator THEN
        avv$active_sou_capabilities := avv$active_sou_capabilities
                                     + $avt$conditional_capabilities [avc$cc_system_admin];
      ELSE
        avv$active_sou_capabilities := avv$active_sou_capabilities
                                     - $avt$conditional_capabilities [avc$cc_system_admin];
      IFEND;

      IF family_administrator THEN
        avv$active_sou_capabilities := avv$active_sou_capabilities
                                     + $avt$conditional_capabilities [avc$cc_family_admin];
      ELSE
        avv$active_sou_capabilities := avv$active_sou_capabilities
                                     - $avt$conditional_capabilities [avc$cc_family_admin];
      IFEND;

      avv$validation_level := $INTEGER (validation_level);

      mmp$create_scratch_segment (amc$heap_pointer, mmc$as_random, ts_segment_pointer, status);
      IF status.normal THEN
        RESET ts_segment_pointer.heap_pointer^;
        osv$task_shared_heap := ts_segment_pointer.heap_pointer;
        mmp$create_scratch_segment (amc$heap_pointer, mmc$as_random, tp_segment_pointer, status);
        IF status.normal THEN
          RESET tp_segment_pointer.heap_pointer^;
          osv$task_private_heap := tp_segment_pointer.heap_pointer;
          mmp$create_scratch_segment (amc$heap_pointer, mmc$as_random, jp_segment_pointer, status);
          IF status.normal THEN
            RESET jp_segment_pointer.heap_pointer^;
            osv$job_pageable_heap := jp_segment_pointer.heap_pointer;
          ELSE
            mmp$delete_scratch_segment (tp_segment_pointer, ignore_status);
            mmp$delete_scratch_segment (ts_segment_pointer, ignore_status);
          IFEND;
        ELSE
          mmp$delete_scratch_segment (ts_segment_pointer, ignore_status);
        IFEND;
      IFEND;

    PROCEND initialize;
?? OLDTITLE ??
  ?IFEND

MODEND avm$validation_interfaces;
