?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Configuration Management: LCU Functions' ??
MODULE cmm$lcu_functions;

{ PURPOSE:
{   This module contains all the Logical Configuration Utility functions.
{
{ DESIGN:
{   Throughout this module, the STATUS variable is set to normal and the function will usually return a null
{ string if an abnormal status is encountered internally.

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clt$data_value
*copyc clt$name
*copyc clt$parameter_list
*copyc clt$parameter_value
*copyc clt$work_area
*copyc cmc$condition_limits
*copyc cme$physical_configuration_mgr
*copyc cmt$element_definition
*copyc cmt$element_selector
*copyc cmt$mass_storage_volume
*copyc iot$unit_interface_table
*copyc jmt$system_supplied_name
?? POP ??
*copyc avp$configuration_administrator
*copyc avp$removable_media_operator
*copyc avp$system_displays
*copyc avp$system_operator
*copyc clp$convert_string_to_integer
*copyc clp$evaluate_parameters
*copyc cmp$count_con_access_job
*copyc cmp$dedicated_maint_active
*copyc cmp$get_channel_definition
*copyc cmp$get_element_definition
*copyc cmp$get_element_information
*copyc cmp$get_element_name_via_lun
*copyc cmp$get_logical_unit_number
*copyc cmp$get_ms_class_on_volume
*copyc cmp$get_parity_status_info
*copyc cmp$get_reservation_info
*copyc cmp$get_unit_number_via_vsn
*copyc cmp$get_unit_type
*copyc cmp$pc_get_element
*copyc cmp$pc_get_logical_unit
*copyc cmp$get_ms_volumes
*copyc cmp$get_ms_volume_info
*copyc cmp$return_lun_info
*copyc cmp$search_peripheral_table
*copyc dmv$active_volume_table
*copyc osp$get_family_names_by_set
*copyc osp$set_status_abnormal
*copyc oss$job_paged_literal
*copyc osv$task_private_heap
*copyc stp$get_active_set_list
*copyc stp$get_volumes_set_name
*copyc stp$get_volumes_in_set
*copyc stv$system_set_name

?? OLDTITLE ??
?? NEWTITLE := 'LCU Functions' ??
?? OLDTITLE ??
?? NEWTITLE := '   $ACTIVE_SETS', EJECT ??

{ PURPOSE:
{   This function provides a list of the names of all the active mass
{   storage sets on the requesting mainframe. The name of the system set
{   is included.

  PROCEDURE [XDCL, #GATE] cmp$$active_sets
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);

{ FUNCTION (cmm$$active_sets) $active_sets (
{ )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
    recend := [
    [1,
    [89, 4, 18, 15, 15, 9, 282],
    clc$function, 0, 0, 0, 0, 0, 0, 0, 'CMM$$ACTIVE_SETS']];

?? FMT (FORMAT := ON) ??
?? POP ??

  VAR
    actual_number_of_sets: stt$number_of_sets,
    index: integer,
    p_active_set_list: ^stt$set_list,
    value: ^clt$data_value;

    status.normal := TRUE;
    NEXT result IN work_area;
    result^.kind := clc$list;
    result^.element_value := NIL;
    result^.link := NIL;
    result^.generated_via_list_rest := FALSE;
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator () OR
             avp$system_displays ()) THEN
      RETURN;
    IFEND;

    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, NIL, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    actual_number_of_sets := 10;
    REPEAT
      PUSH p_active_set_list: [1 .. actual_number_of_sets];
      stp$get_active_set_list (p_active_set_list^, actual_number_of_sets);
    UNTIL (actual_number_of_sets <= UPPERBOUND (p_active_set_list^));

    IF actual_number_of_sets = 0 THEN
      RETURN;
    IFEND;

    value := result;
    FOR index := LOWERBOUND (p_active_set_list^) TO actual_number_of_sets DO
      NEXT value^.element_value IN work_area;
      value^.element_value^.kind := clc$name;
      value^.element_value^.name_value := p_active_set_list^ [index];
      value^.generated_via_list_rest := FALSE;
      IF index < actual_number_of_sets THEN
        NEXT value^.link IN work_area;
        value^.link^.kind := clc$list;
        value^.link^.element_value := NIL;
        value^.link^.link := NIL;
        value^.link^.generated_via_list_rest := FALSE;
        value := value^.link;
      ELSE
        value^.link := NIL;
      IFEND;
    FOREND;

  PROCEND cmp$$active_sets;

?? OLDTITLE ??
?? NEWTITLE := '  $ACTIVE_SET_FAMILIES', EJECT ??

{ PURPOSE:
{   This function provides a list of names of families assigned to the
{   set. If the set is not defined, an empty list is returned.

  PROCEDURE [XDCL, #GATE] cmp$$active_set_families
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);


{   FUNCTION (cmm$$active_set_families) $active_set_families (
{     set: name = $required
{  )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
      recend,
    recend := [
    [1,
    [89, 4, 19, 9, 33, 53, 876],
    clc$function, 1, 1, 1, 0, 0, 0, 0, 'CMM$$ACTIVE_SET_FAMILIES'], [
    ['SET                            ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0
  , 0]],
{ PARAMETER 1
    [[1, 0, clc$name_type], [1, osc$max_name_size]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$set = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

    VAR
      active_family_list: ^array [1 .. * ] of ost$name,
      ignore_status: ost$status,
      index: pmt$family_name_count,
      number_of_families: pmt$family_name_count,
      set_name: stt$set_name,
      value: ^clt$data_value;

    status.normal := TRUE;

    NEXT result IN work_area;
    result^.kind := clc$list;
    result^.element_value := NIL;
    result^.link := NIL;
    result^.generated_via_list_rest := FALSE;
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
            OR avp$system_displays ()) THEN
      RETURN;
    IFEND;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    set_name := pvt [p$set].value^.name_value;
    number_of_families := 10;
    REPEAT
      PUSH active_family_list: [1 .. number_of_families];
      osp$get_family_names_by_set (set_name, active_family_list^, number_of_families, ignore_status);
      IF NOT ignore_status.normal THEN
        RETURN;
      IFEND;
    UNTIL number_of_families <= UPPERBOUND (active_family_list^);
    IF number_of_families = 0 THEN
      RETURN;
    IFEND;
    value := result;
    FOR index := 1 TO number_of_families DO
      NEXT value^.element_value IN work_area;
      value^.element_value^.kind := clc$name;
      value^.element_value^.name_value := active_family_list^ [index];
      value^.generated_via_list_rest := FALSE;
      IF index < number_of_families THEN
        NEXT value^.link IN work_area;
        value^.link^.kind := clc$list;
        value^.link^.element_value := NIL;
        value^.link^.link := NIL;
        value^.link^.generated_via_list_rest := FALSE;
        value := value^.link;
      ELSE
        value^.link := NIL;
      IFEND;
    FOREND;

  PROCEND cmp$$active_set_families;

?? OLDTITLE ??
?? NEWTITLE := '   $ACTIVE_SET_MEMBERS', EJECT ??

{ PURPOSE:
{   This function returns a record for each mass storage volume that is
{   a member of the specified set. If the set is not defined, an empty
{   list is returned.
{ NOTE:
{   The record returned is of the following SCL type:
{   "member_volume" record
{     element_name    : name
{     recorded_vsn    : name 1 .. 6
{     volume_available: boolean
{  recend

  PROCEDURE [XDCL, #GATE] cmp$$active_set_members
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);


{ FUNCTION (cmm$$active_set_members) $active_set_members (
{   set: name = $required
{ )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
      recend,
    recend := [
    [1,
    [89, 4, 18, 14, 23, 26, 448],
    clc$function, 1, 1, 1, 0, 0, 0, 0, 'CMM$$ACTIVE_SET_MEMBERS'], [
    ['SET                            ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0
  , 0]],
{ PARAMETER 1
    [[1, 0, clc$name_type], [1, osc$max_name_size]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$set = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

    VAR
      actual_number_of_members: stt$number_of_members,
      element_name: cmt$element_name,
      local_status: ost$status,
      index: integer,
      lun: iot$logical_unit,
      master_vol: stt$volume_info,
      p_member_vol_list: ^stt$volume_list,
      set_name: stt$set_name,
      value: ^clt$data_value;

    status.normal := TRUE;
    NEXT result IN work_area;
    result^.kind := clc$list;
    result^.element_value := NIL;
    result^.link := NIL;
    result^.generated_via_list_rest := FALSE;
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
              OR avp$system_displays ()) THEN
      RETURN;
    IFEND;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

 { Preset function result to empty list.

    set_name :=  pvt [p$set].value^.name_value;
    actual_number_of_members := 10;
    REPEAT
      PUSH p_member_vol_list: [1 .. actual_number_of_members];
      stp$get_volumes_in_set (set_name, master_vol, p_member_vol_list^,
          actual_number_of_members, local_status);
      IF NOT local_status.normal THEN
        RETURN;
      IFEND;
    UNTIL actual_number_of_members <= UPPERBOUND (p_member_vol_list^);

 { Retrieve info for master volume and make it the first entry in the list

    cmp$get_unit_number_via_vsn (master_vol.recorded_vsn, lun, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;

    cmp$get_element_name_via_lun (lun, element_name, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;

    value := result;
    NEXT value^.element_value IN work_area;
    value^.element_value^.kind := clc$record;
    NEXT value^.element_value^.field_values: [1 .. 3] IN work_area;
    value^.element_value^.field_values^ [1].name := 'ELEMENT_NAME';
    NEXT value^.element_value^.field_values^ [1].value IN work_area;
    value^.element_value^.field_values^ [1].value^.kind := clc$name;
    value^.element_value^.field_values^ [1].value^.name_value := element_name;
    value^.element_value^.field_values^ [2].name := 'RECORDED_VSN';
    NEXT value^.element_value^.field_values^ [2].value IN work_area;
    value^.element_value^.field_values^ [2].value^.kind := clc$name;
    value^.element_value^.field_values^ [2].value^.name_value := master_vol.recorded_vsn;
    value^.element_value^.field_values^ [3].name := 'VOLUME_AVAILABLE';
    NEXT value^.element_value^.field_values^ [3].value IN work_area;
    value^.element_value^.field_values^ [3].value^.kind := clc$boolean;
    value^.element_value^.field_values^ [3].value^.boolean_value.kind := clc$true_false_boolean;
    value^.element_value^.field_values^ [3].value^.boolean_value.value :=
          volume_available (master_vol.recorded_vsn);
    value^.generated_via_list_rest := FALSE;
    value^.link := NIL;
    IF actual_number_of_members = 0 THEN
      RETURN;
    IFEND;

    /get_elements_loop/
    FOR index := LOWERBOUND (p_member_vol_list^) TO actual_number_of_members DO

      cmp$get_unit_number_via_vsn (p_member_vol_list^ [index].recorded_vsn, lun, local_status);
      IF NOT local_status.normal THEN
        IF local_status.condition = dme$recorded_vsn_not_in_lun THEN
          local_status.normal := TRUE;
          CYCLE /get_elements_loop/;
        ELSE
          RETURN;
        IFEND;
      IFEND;

      cmp$get_element_name_via_lun (lun, element_name, local_status);
      IF NOT local_status.normal THEN
        RETURN;
      IFEND;

      NEXT value^.link IN work_area;
      value := value^.link;
      value^.kind := clc$list;
      value^.link := NIL;
      NEXT value^.element_value IN work_area;
      value^.element_value^.kind := clc$record;
      NEXT value^.element_value^.field_values: [1 .. 3] IN work_area;
      value^.element_value^.field_values^ [1].name := 'ELEMENT_NAME';
      NEXT value^.element_value^.field_values^ [1].value IN work_area;
      value^.element_value^.field_values^ [1].value^.kind := clc$name;
      value^.element_value^.field_values^ [1].value^.name_value := element_name;
      value^.element_value^.field_values^ [2].name := 'RECORDED_VSN';
      NEXT value^.element_value^.field_values^ [2].value IN work_area;
      value^.element_value^.field_values^ [2].value^.kind := clc$name;
      value^.element_value^.field_values^ [2].value^.name_value := p_member_vol_list^ [index].recorded_vsn;
      value^.element_value^.field_values^ [3].name := 'VOLUME_AVAILABLE';
      NEXT value^.element_value^.field_values^ [3].value IN work_area;
      value^.element_value^.field_values^ [3].value^.kind := clc$boolean;
      value^.element_value^.field_values^ [3].value^.boolean_value.kind := clc$true_false_boolean;
      value^.element_value^.field_values^ [3].value^.boolean_value.value :=
            volume_available (p_member_vol_list^ [index].recorded_vsn);
      value^.generated_via_list_rest := FALSE;
    FOREND /get_elements_loop/;

  PROCEND cmp$$active_set_members;

?? OLDTITLE ??
?? NEWTITLE := '  $CHANNEL_PORT', EJECT ??

{ PURPOSE:
{   This function returns the port value of a CIO channel.

  PROCEDURE [XDCL, #GATE] cmp$$channel_port
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);

{ FUNCTION (cmm$$channel_port) $channel_port, $cp (
{   channel: name = $required
{   downline_element: name = $required
{   iou: name = IOU0
{   )

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 3] of clt$pdt_parameter_name,
        parameters: array [1 .. 3] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        type2: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        type3: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
          default_value: string (4),
        recend,
      recend := [[1, [88, 11, 2, 12, 34, 56, 789], clc$function, 3, 3, 2, 0, 0, 0, 0, 'CMM$$CHANNEL_PORT'],
            [['CHANNEL                        ', clc$nominal_entry, 1],
            ['DOWNLINE_ELEMENT               ', clc$nominal_entry, 2],
            ['IOU                            ', clc$nominal_entry, 3]], [

{ CHANNEL

      [1, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0, 0],

{ DOWNLINE_ELEMENT

      [2, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0, 0],

{ IOU

      [3, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$optional_default_parameter, 0,
            4]],

{ CHANNEL

      [[1, 0, clc$name_type], [1, osc$max_name_size]],

{ DOWNLINE_ELEMENT

      [[1, 0, clc$name_type], [1, osc$max_name_size]],

{ IOU

      [[1, 0, clc$name_type], [1, osc$max_name_size], 'IOU0']];

?? POP ??

    CONST
      p$channel = 1,
      p$downline_element = 2,
      p$iou = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    VAR
      channel_descriptor: cmt$channel_descriptor,
      channel_definition: cmt$data_channel_definition,
      data_port: cmt$data_storage_port_number,
      element: ^cmt$element_definition,
      element_name: cmt$element_name,
      ignore_status: ost$status,
      iou_name: cmt$element_name,
      port: cmt$controller_port_number,
      upline_channel: cmt$data_channel_definition;

    status.normal := TRUE;

{ Preset empty string so SOMETHING will be returned no matter what else goes wrong...

    NEXT result IN work_area;
    result^.kind := clc$string;
    NEXT result^.string_value: [0] IN work_area;

  /main_program/
    BEGIN
      IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
           OR avp$system_displays ()) THEN
        EXIT /main_program/;
      IFEND;
      clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;
      channel_descriptor.use_logical_identification := TRUE;
      channel_descriptor.name := pvt [p$channel].value^.name_value;
      channel_descriptor.iou := iou_name;
      element_name := pvt [p$downline_element].value^.name_value;
      iou_name := pvt [p$iou].value^.name_value;
      cmp$get_channel_definition (channel_descriptor, channel_definition, ignore_status);
      IF NOT ignore_status.normal THEN
        IF ignore_status.condition <> cme$lcm_element_not_found THEN
          EXIT /main_program/;
        IFEND;
      IFEND;

      IF NOT channel_definition.concurrent THEN

{ Non concurrent channels have no port.

        EXIT /main_program/;
      IFEND;
      cmp$pc_get_element (element_name, iou_name, element, ignore_status);
      IF NOT ignore_status.normal THEN
        EXIT /main_program/;
      IFEND;

      IF element^.element_type = cmc$controller_element THEN

      /upline_connection_loop1/
        FOR port := LOWERVALUE (cmt$controller_port_number) TO UPPERVALUE (cmt$controller_port_number) DO
          IF element^.controller.connection.port [port].configured THEN
            channel_descriptor.use_logical_identification := TRUE;
            channel_descriptor.iou := element^.controller.connection.port [port].iou;
            channel_descriptor.name := element^.controller.connection.port [port].element_name;
            cmp$get_channel_definition (channel_descriptor, upline_channel, ignore_status);
            IF NOT ignore_status.normal THEN
              EXIT /main_program/;
            IFEND;
            IF (upline_channel.number = channel_definition.number) AND
                  (element^.controller.connection.port [port].iou = iou_name) THEN
              IF upline_channel.port = cmc$port_a THEN
                result^.string_value^ (1, 1) := 'A';
              ELSE { upline_channel.port = cmc$port_b
                result^.string_value^ (1, 1) := 'B';
              IFEND;
              EXIT /upline_connection_loop1/;
            IFEND;
          IFEND;
        FOREND /upline_connection_loop1/;

      ELSEIF element^.element_type = cmc$storage_device_element THEN

      /upline_connection_loop2/
        FOR data_port := LOWERVALUE (cmt$data_storage_port_number)
              TO UPPERVALUE (cmt$data_storage_port_number) DO
          IF (element^.storage_device.connection.port [data_port].configured) AND
                (element^.storage_device.connection.port [data_port].upline_connection_type =
                cmc$data_channel_element) THEN
            channel_descriptor.use_logical_identification := TRUE;
            channel_descriptor.iou := element^.storage_device.connection.port [data_port].iou;
            channel_descriptor.name := element^.storage_device.connection.port [data_port].element_name;
            cmp$get_channel_definition (channel_descriptor, upline_channel, ignore_status);
            IF NOT ignore_status.normal THEN
              EXIT /main_program/;
            IFEND;
            IF (upline_channel.number = channel_definition.number) AND
                  (element^.storage_device.connection.port [port].iou = iou_name) THEN
              IF upline_channel.port = cmc$port_a THEN
                result^.string_value^ (1, 1) := 'A';
              ELSE { upline_channel.port = cmc$port_b THEN
                result^.string_value^ (1, 1) := 'B';
              IFEND;
              EXIT /upline_connection_loop2/;
            IFEND;
          IFEND;
        FOREND /upline_connection_loop2/;
      IFEND;
    END /main_program/;

  PROCEND cmp$$channel_port;

?? OLDTITLE ??
?? NEWTITLE := '  $ELEMENT', EJECT ??

{ PURPOSE:
{   This function returns a specified attribute of a given element.

  PROCEDURE [XDCL, #GATE] cmp$$element
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);

{    FUNCTION (cmm$$element) $element (
{      element: name = $required
{      attribute: key
{          (application_information, ai)
{          (assigned_job_identification, aji)
{          (assigned_to_job, atj)
{          (concurrent_maintenance_count, cmc)
{          (dedicated_maintenance_active, dma)
{          (densities_in_operation, dio)
{          (device_allocation_unit_size, daus)
{          (device_class, dc)
{          (element_capability, ec)
{          (element_exists, ee)
{          (element_identification, ei)
{          (element_state, es)
{          (element_type, et)
{          (external_vsn, evsn, ev)
{          (iou_program_name, ioupn, ipn)
{          (mass_storage_available, msa)
{          (mass_storage_capacity, msc)
{          (mass_storage_set_name, mssn)
{          (mass_storage_volume_active, msva)
{          (mass_storage_volume_classes, msvc)
{          (mass_storage_volume_online, msvo)
{          (off_line_drive_number, oldn)
{          (parity_protection_enabled, ppe)
{          (recorded_vsn, rvsn, rv)
{          (repair_action_required, rar)
{          (repair_attempted, ra)
{          (reservable_element, re)
{          (reserved_to_job, rtj)
{          (reserving_job_identification, rji)
{          (restoring_drive, rd)
{          (serial_number, sn)
{          (site_information, si)
{          (system_critical_element, sce)
{        keyend = $required
{      iou: name = IOU0
{      )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 3] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$keyword_type_qualifier,
        keyword_specs: array [1 .. 69] of clt$keyword_specification,
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
        default_value: string (4),
      recend,
    recend := [
    [1,
    [94, 12, 21, 14, 50, 42, 497],
    clc$function, 3, 3, 2, 0, 0, 0, 0, 'CMM$$ELEMENT'], [
    ['ATTRIBUTE                      ',clc$nominal_entry, 2],
    ['ELEMENT                        ',clc$nominal_entry, 1],
    ['IOU                            ',clc$nominal_entry, 3]],
    [
{ PARAMETER 1
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation,
  clc$standard_parameter_checking, 5, clc$required_parameter, 0, 0],
{ PARAMETER 2
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation,
  clc$standard_parameter_checking, 2560, clc$required_parameter, 0, 0],
{ PARAMETER 3
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation,
  clc$standard_parameter_checking, 5, clc$optional_default_parameter, 0, 4]],
{ PARAMETER 1
    [[1, 0, clc$name_type], [1, osc$max_name_size]],
{ PARAMETER 2
    [[1, 0, clc$keyword_type], [69], [
    ['AI                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 1],
    ['AJI                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 2],
    ['APPLICATION_INFORMATION        ', clc$nominal_entry,
  clc$normal_usage_entry, 1],
    ['ASSIGNED_JOB_IDENTIFICATION    ', clc$nominal_entry,
  clc$normal_usage_entry, 2],
    ['ASSIGNED_TO_JOB                ', clc$nominal_entry,
  clc$normal_usage_entry, 3],
    ['ATJ                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 3],
    ['CMC                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 4],
    ['CONCURRENT_MAINTENANCE_COUNT   ', clc$nominal_entry,
  clc$normal_usage_entry, 4],
    ['DAUS                           ', clc$abbreviation_entry,
  clc$normal_usage_entry, 7],
    ['DC                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 8],
    ['DEDICATED_MAINTENANCE_ACTIVE   ', clc$nominal_entry,
  clc$normal_usage_entry, 5],
    ['DENSITIES_IN_OPERATION         ', clc$nominal_entry,
  clc$normal_usage_entry, 6],
    ['DEVICE_ALLOCATION_UNIT_SIZE    ', clc$nominal_entry,
  clc$normal_usage_entry, 7],
    ['DEVICE_CLASS                   ', clc$nominal_entry,
  clc$normal_usage_entry, 8],
    ['DIO                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 6],
    ['DMA                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 5],
    ['EC                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 9],
    ['EE                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 10],
    ['EI                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 11],
    ['ELEMENT_CAPABILITY             ', clc$nominal_entry,
  clc$normal_usage_entry, 9],
    ['ELEMENT_EXISTS                 ', clc$nominal_entry,
  clc$normal_usage_entry, 10],
    ['ELEMENT_IDENTIFICATION         ', clc$nominal_entry,
  clc$normal_usage_entry, 11],
    ['ELEMENT_STATE                  ', clc$nominal_entry,
  clc$normal_usage_entry, 12],
    ['ELEMENT_TYPE                   ', clc$nominal_entry,
  clc$normal_usage_entry, 13],
    ['ES                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 12],
    ['ET                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 13],
    ['EV                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 14],
    ['EVSN                           ', clc$alias_entry,
  clc$normal_usage_entry, 14],
    ['EXTERNAL_VSN                   ', clc$nominal_entry,
  clc$normal_usage_entry, 14],
    ['IOUPN                          ', clc$alias_entry,
  clc$normal_usage_entry, 15],
    ['IOU_PROGRAM_NAME               ', clc$nominal_entry,
  clc$normal_usage_entry, 15],
    ['IPN                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 15],
    ['MASS_STORAGE_AVAILABLE         ', clc$nominal_entry,
  clc$normal_usage_entry, 16],
    ['MASS_STORAGE_CAPACITY          ', clc$nominal_entry,
  clc$normal_usage_entry, 17],
    ['MASS_STORAGE_SET_NAME          ', clc$nominal_entry,
  clc$normal_usage_entry, 18],
    ['MASS_STORAGE_VOLUME_ACTIVE     ', clc$nominal_entry,
  clc$normal_usage_entry, 19],
    ['MASS_STORAGE_VOLUME_CLASSES    ', clc$nominal_entry,
  clc$normal_usage_entry, 20],
    ['MASS_STORAGE_VOLUME_ONLINE     ', clc$nominal_entry,
  clc$normal_usage_entry, 21],
    ['MSA                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 16],
    ['MSC                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 17],
    ['MSSN                           ', clc$abbreviation_entry,
  clc$normal_usage_entry, 18],
    ['MSVA                           ', clc$abbreviation_entry,
  clc$normal_usage_entry, 19],
    ['MSVC                           ', clc$abbreviation_entry,
  clc$normal_usage_entry, 20],
    ['MSVO                           ', clc$abbreviation_entry,
  clc$normal_usage_entry, 21],
    ['OFF_LINE_DRIVE_NUMBER          ', clc$nominal_entry,
  clc$normal_usage_entry, 22],
    ['OLDN                           ', clc$abbreviation_entry,
  clc$normal_usage_entry, 22],
    ['PARITY_PROTECTION_ENABLED      ', clc$nominal_entry,
  clc$normal_usage_entry, 23],
    ['PPE                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 23],
    ['RA                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 26],
    ['RAR                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 25],
    ['RD                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 30],
    ['RE                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 27],
    ['RECORDED_VSN                   ', clc$nominal_entry,
  clc$normal_usage_entry, 24],
    ['REPAIR_ACTION_REQUIRED         ', clc$nominal_entry,
  clc$normal_usage_entry, 25],
    ['REPAIR_ATTEMPTED               ', clc$nominal_entry,
  clc$normal_usage_entry, 26],
    ['RESERVABLE_ELEMENT             ', clc$nominal_entry,
  clc$normal_usage_entry, 27],
    ['RESERVED_TO_JOB                ', clc$nominal_entry,
  clc$normal_usage_entry, 28],
    ['RESERVING_JOB_IDENTIFICATION   ', clc$nominal_entry,
  clc$normal_usage_entry, 29],
    ['RESTORING_DRIVE                ', clc$nominal_entry,
  clc$normal_usage_entry, 30],
    ['RJI                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 29],
    ['RTJ                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 28],
    ['RV                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 24],
    ['RVSN                           ', clc$alias_entry,
  clc$normal_usage_entry, 24],
    ['SCE                            ', clc$abbreviation_entry,
  clc$normal_usage_entry, 33],
    ['SERIAL_NUMBER                  ', clc$nominal_entry,
  clc$normal_usage_entry, 31],
    ['SI                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 32],
    ['SITE_INFORMATION               ', clc$nominal_entry,
  clc$normal_usage_entry, 32],
    ['SN                             ', clc$abbreviation_entry,
  clc$normal_usage_entry, 31],
    ['SYSTEM_CRITICAL_ELEMENT        ', clc$nominal_entry,
  clc$normal_usage_entry, 33]]
    ],
{ PARAMETER 3
    [[1, 0, clc$name_type], [1, osc$max_name_size],
    'IOU0']];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$element = 1,
      p$attribute = 2,
      p$iou = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    CONST
      init_offln_drv_num = 0ff(16),    {NOSVE initialization value for 'off_line_drive_number'.}
      no_drives_offline = 0fe(16);     {Value set by driver to indicate no drives offline.}

    VAR
      assigned_jsn: jmt$system_supplied_name,
      assigned_to_job: boolean,
      attribute: clt$keyword,
      call_program_interface: boolean,
      cm_unit_type: cmt$unit_type,
      element: ^cmt$element_definition,
      element_def: ^cmt$element_definition,
      element_descriptor: cmt$element_descriptor,
      element_exists: boolean,
      element_info: array [1 .. 1] of cmt$element_info_item,
      element_name: cmt$element_name,
      element_reservation: cmt$element_reservation,
      found: boolean,
      ignore: ost$status,
      io_unit_type: iot$unit_type,
      iou_name: cmt$element_name,
      jc: integer,
      list_count: integer,
      logical_unit_number: iot$logical_unit,
      ms_class: cmt$ms_class_members,
      ms_class_info: cmt$ms_class_info,
      name_list_index: integer,
      not_in_configuration: boolean,
      parity_status: iot$unit_status,
      port: cmt$data_storage_port_number,
      read_only: boolean,
      reservable_element: boolean,
      reserved_to_job: boolean,
      reserving_job: jmt$system_supplied_name,
      set_index: rmt$density,
      set_name: stt$set_name,
      string_p: ^string ( * ),
      table_index: integer,
      unit_class: cmt$unit_class,
      value: ^clt$data_value;

    status.normal := TRUE;

  /main_program/
    BEGIN
      {
      { Preset empty string so SOMETHING will be returned no matter what else goes wrong...
      {
      NEXT result IN work_area;
      result^.kind := clc$string;
      NEXT result^.string_value: [0] IN work_area;
      IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
            OR avp$system_displays ()) THEN
        EXIT /main_program/;
      IFEND;

      clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      attribute := pvt [p$attribute].value^.keyword_value;
      element_name := pvt [p$element].value^.name_value;
      iou_name := pvt [p$iou].value^.name_value;

      cmp$pc_get_element (element_name, iou_name, element_def, ignore);
      element_exists := ignore.normal;
      not_in_configuration := NOT element_exists;

      cmp$get_logical_unit_number (element_name, logical_unit_number, ignore);

      IF attribute = 'ELEMENT_EXISTS' THEN
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        result^.boolean_value.value := element_exists;
        EXIT /main_program/;
      ELSEIF not_in_configuration THEN
        EXIT /main_program/;
      IFEND;

      element_descriptor.element_type := element_def^.element_type;

{ Set up element descriptor for CMP$GET_ELEMENT_INFORMATION.  Note that this will only be called for
{ certain values of ATTRIBUTE.

      CASE element_def^.element_type OF
      = cmc$channel_adapter_element, cmc$communications_element, cmc$controller_element,
            cmc$storage_device_element, cmc$external_processor_element =
        element_descriptor.peripheral_descriptor.use_logical_identification := TRUE;
        element_descriptor.peripheral_descriptor.element_name := element_name;
      = cmc$data_channel_element =
        element_descriptor.channel_descriptor.use_logical_identification := TRUE;
        element_descriptor.channel_descriptor.iou := iou_name;
        element_descriptor.channel_descriptor.name := element_name;
      ELSE
        EXIT /main_program/;
      CASEND;

      call_program_interface := TRUE;

      IF attribute = 'APPLICATION_INFORMATION' THEN
        element_info [1].selector := cmc$application_string_size;
      ELSEIF attribute = 'DENSITIES_IN_OPERATION' THEN
        element_info [1].selector := cmc$element_capability;
      ELSEIF attribute = 'DEVICE_ALLOCATION_UNIT_SIZE' THEN
        element_info [1].selector := cmc$dau_size;
      ELSEIF attribute = 'DEVICE_CLASS' THEN
        element_info [1].selector := cmc$device_class;
      ELSEIF attribute = 'ELEMENT_CAPABILITY' THEN
        element_info [1].selector := cmc$element_capability;
      ELSEIF attribute = 'ELEMENT_IDENTIFICATION' THEN
        element_info [1].selector := cmc$product_identification;
      ELSEIF attribute = 'ELEMENT_STATE' THEN
        element_info [1].selector := cmc$element_status;
      ELSEIF attribute = 'EXTERNAL_VSN' THEN
        element_info [1].selector := cmc$external_vsn;
      ELSEIF attribute = 'MASS_STORAGE_AVAILABLE' THEN
        element_info [1].selector := cmc$mass_storage_available;
      ELSEIF attribute = 'MASS_STORAGE_CAPACITY' THEN
        element_info [1].selector := cmc$mass_storage_capacity;
      ELSEIF attribute = 'MASS_STORAGE_SET_NAME' THEN
        element_info [1].selector := cmc$recorded_vsn;
      ELSEIF attribute = 'MASS_STORAGE_VOLUME_ACTIVE' THEN
        element_info [1].selector := cmc$volume_active;
      ELSEIF attribute = 'MASS_STORAGE_VOLUME_CLASSES' THEN
        element_info [1].selector := cmc$recorded_vsn;
      ELSEIF attribute = 'MASS_STORAGE_VOLUME_ONLINE' THEN
        element_info [1].selector := cmc$volume_online;
      ELSEIF attribute = 'RECORDED_VSN' THEN
        element_info [1].selector := cmc$recorded_vsn;
      ELSEIF attribute = 'REPAIR_ATTEMPTED' THEN
        element_info [1].selector := cmc$element_status;
      ELSEIF attribute = 'SERIAL_NUMBER' THEN
        element_info [1].selector := cmc$serial_number;
      ELSEIF attribute = 'SITE_INFORMATION' THEN
        element_info [1].selector := cmc$site_info_string_size;
      ELSEIF attribute = 'SYSTEM_CRITICAL_ELEMENT' THEN
        element_info [1].selector := cmc$system_critical_element;
      ELSE
        call_program_interface := FALSE;
      IFEND;

      IF call_program_interface THEN
        cmp$get_element_information (element_descriptor, element_info, ignore);
        IF NOT ignore.normal THEN
          EXIT /main_program/;
        IFEND;
        IF NOT element_info [1].item_returned THEN
          IF element_info [1].selector <> cmc$device_class THEN
            EXIT /main_program/;
          IFEND;
        IFEND;
      IFEND;

{ The following code is logically a 'CASE attribute OF' construct...

      IF attribute = 'APPLICATION_INFORMATION' THEN
        IF element_info [1].application_info_string_size > 0 THEN
          NEXT string_p: [element_info [1].application_info_string_size] in work_area;
          element_info [1].selector := cmc$application_information;
          element_info [1].application_information := string_p;
          cmp$get_element_information (element_descriptor, element_info, ignore);
          IF NOT ignore.normal THEN
            EXIT /main_program/;
          IFEND;
          result^.string_value := element_info [1].application_information;
        IFEND;
      ELSEIF attribute = 'ASSIGNED_JOB_IDENTIFICATION' THEN
        IF logical_unit_number <> 0 THEN
          cmp$return_lun_info (logical_unit_number, assigned_to_job, assigned_jsn);
          result^.kind := clc$name;
          IF assigned_to_job THEN
            result^.name_value := assigned_jsn;
          ELSE
            result^.name_value := ' ';
          IFEND;
        IFEND;

      ELSEIF attribute = 'ASSIGNED_TO_JOB' THEN
        IF logical_unit_number <> 0 THEN
          cmp$return_lun_info (logical_unit_number, assigned_to_job, assigned_jsn);
          result^.kind := clc$boolean;
          result^.boolean_value.kind := clc$true_false_boolean;
          result^.boolean_value.value := assigned_to_job;
        IFEND;

      ELSEIF attribute = 'CONCURRENT_MAINTENANCE_COUNT' THEN
        cmp$search_peripheral_table (element_descriptor, element_reservation, not_in_configuration,
              table_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/;
        IFEND;
        result^.kind := clc$integer;
        result^.integer_value.radix := 10;
        result^.integer_value.radix_specified := FALSE;
        cmp$count_con_access_job (table_index, result^.integer_value.value, status);
        IF NOT status.normal THEN
          EXIT /main_program/;
        IFEND;

      ELSEIF attribute = 'DEDICATED_MAINTENANCE_ACTIVE' THEN
        cmp$search_peripheral_table (element_descriptor, element_reservation, not_in_configuration,
              table_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/;
        IFEND;
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        result^.boolean_value.value := cmp$dedicated_maint_active (table_index);

      ELSEIF attribute = 'DENSITIES_IN_OPERATION' THEN
        list_count := 0;
        IF element_info [1].element_capability.element_type = cmc$storage_device_element THEN
          IF element_info [1].element_capability.device_class = rmc$magnetic_tape_device THEN
            FOR set_index := LOWERVALUE (rmt$density) TO UPPERVALUE (rmt$density) DO
              IF set_index IN element_info [1].element_capability.densities THEN
                list_count := list_count + 1;
              IFEND;
            FOREND;
          ELSE
            EXIT /main_program/;
          IFEND;
        IFEND;
        IF list_count > 0 THEN
          result^.kind := clc$array;
          NEXT result^.array_value: [1 .. list_count] IN work_area;
          name_list_index := 1;
          FOR set_index := LOWERVALUE (rmt$density) TO UPPERVALUE (rmt$density) DO
            IF set_index IN element_info [1].element_capability.densities THEN
              NEXT result^.array_value^ [name_list_index] IN work_area;
              result^.array_value^ [name_list_index]^.kind := clc$name;
              CASE set_index OF
              = rmc$800 =
                result^.array_value^ [name_list_index]^.name_value := 'MT9$800';
              = rmc$1600 =
                result^.array_value^ [name_list_index]^.name_value := 'MT9$1600';
              = rmc$6250 =
                result^.array_value^ [name_list_index]^.name_value := 'MT9$6250';
              = rmc$38000 =
                result^.array_value^ [name_list_index]^.name_value := 'MT18$38000';
              ELSE
                result^.array_value^ [name_list_index]^.name_value := ' ';
              CASEND;
              name_list_index := name_list_index + 1;
            IFEND;
          FOREND;
        IFEND;

      ELSEIF attribute = 'DEVICE_ALLOCATION_UNIT_SIZE' THEN
        result^.kind := clc$integer;
        result^.integer_value.radix := 10;
        result^.integer_value.radix_specified := FALSE;
        result^.integer_value.value := element_info [1].dau_size;

      ELSEIF attribute = 'DEVICE_CLASS' THEN
        result^.kind := clc$keyword;
        CASE element_info [1].device_class OF
        = rmc$magnetic_tape_device =
          result^.keyword_value := 'MAGNETIC_TAPE';
        = rmc$mass_storage_device =
          result^.keyword_value := 'MASS_STORAGE';
        = rmc$network_device =
          result^.keyword_value := 'NETWORK_DEVICE';
        = rmc$rhfam_device =
          result^.keyword_value := 'RHFAM_DEVICE';
        ELSE
          result^.keyword_value := ' ';
        CASEND;
        IF NOT element_info [1].item_returned THEN
          IF element_def^.element_type = cmc$storage_device_element THEN
            cmp$get_unit_type (element_def^.product_id, cm_unit_type, io_unit_type, unit_class, found);
            IF cm_unit_type = cmc$foreign_unit THEN
              NEXT result^.string_value: [12] IN work_area;
              result^.string_value^ := 'MASS_STORAGE';
            IFEND;
          IFEND;
        IFEND;

      ELSEIF attribute = 'ELEMENT_CAPABILITY' THEN
        read_only := FALSE;
        IF element_info [1].element_capability.element_type = cmc$storage_device_element THEN
          IF element_info [1].element_capability.device_class = rmc$magnetic_tape_device THEN
            read_only := element_info [1].element_capability.write_inhibited;
          IFEND;
        ELSE
          EXIT /main_program/;
        IFEND;
        result^.kind := clc$array;
        IF read_only THEN
          NEXT result^.array_value: [1 .. 1] IN work_area;
          NEXT result^.array_value^ [1] IN work_area;
          result^.array_value^ [1]^.kind := clc$name;
          result^.array_value^ [1]^.name_value := 'READ';
        ELSE
          NEXT result^.array_value: [1 .. 2] IN work_area;
          NEXT result^.array_value^ [1] IN work_area;
          result^.array_value^ [1]^.kind := clc$name;
          result^.array_value^ [1]^.name_value := 'READ';
          NEXT result^.array_value^ [2] IN work_area;
          result^.array_value^ [2]^.kind := clc$name;
          result^.array_value^ [2]^.name_value := 'WRITE';
        IFEND;

      ELSEIF attribute = 'ELEMENT_IDENTIFICATION' THEN
        result^.kind := clc$name;
        result^.name_value (1, 6) := element_info [1].product_identification.product_number;
        result^.name_value (7, 1) := element_info [1].product_identification.underscore;
        result^.name_value (8, * ) := element_info [1].product_identification.model_number;

      ELSEIF attribute = 'ELEMENT_STATE' THEN
        result^.kind := clc$keyword;
        CASE element_info [1].element_status.state OF
        = cmc$down =
          result^.keyword_value := 'DOWN';
        = cmc$off =
          result^.keyword_value := 'OFF';
        = cmc$on =
          result^.keyword_value := 'ON';
        ELSE
          result^.keyword_value := ' ';
        CASEND;

      ELSEIF attribute = 'ELEMENT_TYPE' THEN
        result^.kind := clc$keyword;
        CASE element_def^.element_type OF
        = cmc$central_memory_element =
          result^.keyword_value := 'CENTRAL_MEMORY';
        = cmc$central_processor_element =
          result^.keyword_value := 'CENTRAL_PROCESSOR';
        = cmc$channel_adapter_element =
          result^.keyword_value := 'CHANNEL_ADAPTER';
        = cmc$communications_element =
          result^.keyword_value := 'COMMUNICATIONS_ELEMENT';
        = cmc$controller_element =
          result^.keyword_value := 'CONTROLLER';
        = cmc$data_channel_element =
          result^.keyword_value := 'DATA_CHANNEL';
        = cmc$external_processor_element =
          result^.keyword_value := 'EXTERNAL_PROCESSOR';
        = cmc$iou_element =
          result^.keyword_value := 'IOU';
        = cmc$mainframe_element =
          result^.keyword_value := 'MAINFRAME';
        = cmc$pp_element =
          result^.keyword_value := 'PP';
        = cmc$storage_device_element =
          result^.keyword_value := 'STORAGE_DEVICE';
        ELSE
          result^.keyword_value := ' ';
        CASEND;

      ELSEIF attribute = 'EXTERNAL_VSN' THEN
        result^.kind := clc$string;
        NEXT result^.string_value: [6] IN work_area;
        result^.string_value^ := element_info [1].external_vsn;

      ELSEIF attribute = 'IOU_PROGRAM_NAME' THEN
        result^.kind := clc$name;
        CASE element_def^.element_type OF
        = cmc$channel_adapter_element =
          result^.name_value := element_def^.channel_adapter.peripheral_driver_name;
        = cmc$communications_element =
          result^.name_value := element_def^.communications_element.peripheral_driver_name;
        = cmc$controller_element =
          result^.name_value := element_def^.controller.peripheral_driver_name;
        = cmc$storage_device_element =
          IF element_def^.product_id.product_number = '  $887' THEN
            result^.name_value := 'E9S887';
          ELSE

          /find_controller_loop/
            FOR port := LOWERVALUE (cmt$data_storage_port_number)
                  TO UPPERVALUE (cmt$data_storage_port_number) DO
              IF element_def^.storage_device.connection.port [port].configured THEN
                cmp$pc_get_element (element_def^.storage_device.connection.port [port].element_name, iou_name,
                      element, ignore);
                IF ignore.normal THEN
                  IF element^.element_type = cmc$controller_element THEN
                    result^.name_value := element^.controller.peripheral_driver_name;
                    EXIT /find_controller_loop/;
                  IFEND;
                IFEND;
              IFEND;
            FOREND /find_controller_loop/;
          IFEND;
        ELSE
          result^.name_value := ' ';
        CASEND;

      ELSEIF attribute = 'MASS_STORAGE_AVAILABLE' THEN
        result^.kind := clc$integer;
        result^.integer_value.radix := 10;
        result^.integer_value.radix_specified := FALSE;
        IF element_info [1].item_returned THEN
          result^.integer_value.value := element_info [1].available_capacity;
        ELSE
          result^.integer_value.value := 0;
        IFEND;

      ELSEIF attribute = 'MASS_STORAGE_CAPACITY' THEN
        result^.kind := clc$integer;
        result^.integer_value.radix := 10;
        result^.integer_value.radix_specified := FALSE;
        IF element_info [1].item_returned THEN
          result^.integer_value.value := element_info [1].total_capacity;
        ELSE
          result^.integer_value.value := 0;
        IFEND;

      ELSEIF attribute = 'MASS_STORAGE_SET_NAME' THEN
        result^.kind := clc$name;
        IF logical_unit_number <> 0 THEN
          IF element_def^.element_type = cmc$storage_device_element THEN
            IF element_info [1].recorded_vsn <> ' ' THEN
              stp$get_volumes_set_name (element_info [1].recorded_vsn, set_name, ignore);
              IF ignore.normal THEN
                result^.name_value := set_name;
              IFEND;
            IFEND;
          IFEND;
        ELSE
          result^.name_value := ' ';
        IFEND;

      ELSEIF attribute = 'MASS_STORAGE_VOLUME_ACTIVE' THEN
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        IF element_info [1].item_returned THEN
          result^.boolean_value.value := element_info [1].active;
        ELSE
          result^.boolean_value.value := FALSE;
        IFEND;

      ELSEIF attribute = 'MASS_STORAGE_VOLUME_CLASSES' THEN
        result^.kind := clc$list;
        result^.element_value := NIL;
        result^.link := NIL;
        result^.generated_via_list_rest := FALSE;

        IF logical_unit_number <> 0 THEN
          IF element_def^.element_type = cmc$storage_device_element THEN
            IF element_info [1].recorded_vsn <> ' ' THEN
              cmp$get_ms_class_on_volume (element_info [1].recorded_vsn, found, ms_class_info);
              IF NOT found THEN
                RETURN;
              IFEND;
            IFEND;
          IFEND;
        IFEND;

        value := NIL;
      /build_list/
        FOR ms_class := LOWERBOUND (ms_class_info.classes) TO UPPERBOUND(ms_class_info.classes) DO
          IF NOT ms_class_info.classes [ms_class] THEN
            CYCLE /build_list/;
          IFEND;

          IF value = NIL THEN
            value := result;
          ELSE
            NEXT value^.link IN work_area;
            value^.link^.kind := clc$list;
            value^.link^.generated_via_list_rest := FALSE;
            value := value^.link;
            value^.link := NIL;
          IFEND;

          NEXT value^.element_value IN work_area;
          value^.element_value^.kind := clc$string;
          NEXT value^.element_value^.string_value: [1] IN work_area;
          value^.element_value^.string_value^(1) := ms_class;
          value^.generated_via_list_rest := FALSE;
        FOREND /build_list/;

      ELSEIF attribute = 'MASS_STORAGE_VOLUME_ONLINE' THEN
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        IF element_info [1].item_returned THEN
          result^.boolean_value.value := element_info [1].online;
        ELSE
          result^.boolean_value.value := FALSE;
        IFEND;

      ELSEIF attribute = 'OFF_LINE_DRIVE_NUMBER' THEN
        IF (((element_def^.product_id.product_number = ' $5833') OR
             (element_def^.product_id.product_number = ' $5838') OR
             (element_def^.product_id.product_number = '$47444') OR
             (element_def^.product_id.product_number = ' $5837')) AND
               ((element_def^.product_id.model_number = '1P ') OR
                (element_def^.product_id.model_number = '3P '))) THEN

            cmp$get_parity_status_info (element_name, parity_status, status);
            IF NOT status.normal THEN
              EXIT /main_program/;
            IFEND;
            IF (parity_status.off_line_drive_number = init_offln_drv_num) OR
                  (parity_status.off_line_drive_number = no_drives_offline) THEN
              EXIT /main_program/;
            ELSE
              result^.kind := clc$integer;
              result^.integer_value.radix := 10;
              result^.integer_value.radix_specified := FALSE;
              result^.integer_value.value := parity_status.off_line_drive_number;
            IFEND;
        IFEND;

        ELSEIF attribute = 'PARITY_PROTECTION_ENABLED' THEN
        IF (((element_def^.product_id.product_number = ' $5833') OR
             (element_def^.product_id.product_number = ' $5838') OR
             (element_def^.product_id.product_number = '$47444') OR
             (element_def^.product_id.product_number = ' $5837')) AND
               ((element_def^.product_id.model_number = '1P ') OR
                (element_def^.product_id.model_number = '3P '))) THEN

              cmp$get_parity_status_info (element_name, parity_status, status);
              IF NOT status.normal THEN
                EXIT /main_program/;
              IFEND;
              IF parity_status.off_line_drive_number <> init_offln_drv_num THEN
                result^.kind := clc$boolean;
                result^.boolean_value.kind := clc$true_false_boolean;
                result^.boolean_value.value := parity_status.parity_protection_enabled;
              IFEND;
          IFEND;

      ELSEIF attribute = 'RECORDED_VSN' THEN
        result^.kind := clc$name;
        result^.name_value := element_info [1].recorded_vsn;

      ELSEIF attribute = 'REPAIR_ACTION_REQUIRED' THEN
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        result^.boolean_value.value := FALSE;

      ELSEIF attribute = 'REPAIR_ATTEMPTED' THEN
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        IF (element_info [1].element_status.state = cmc$down) OR
              (element_info [1].element_status.state = cmc$off) THEN
          result^.boolean_value.value := element_info [1].element_status.repair_attempted;
        ELSE
          result^.boolean_value.value := FALSE;
        IFEND;

      ELSEIF attribute = 'RESERVABLE_ELEMENT' THEN
        cmp$search_peripheral_table (element_descriptor, element_reservation, not_in_configuration,
              table_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/;
        IFEND;
        cmp$get_reservation_info (table_index, reservable_element, reserved_to_job, reserving_job);
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        result^.boolean_value.value := reservable_element;

      ELSEIF attribute = 'RESERVED_TO_JOB' THEN
        cmp$search_peripheral_table (element_descriptor, element_reservation, not_in_configuration,
              table_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/;
        IFEND;
        cmp$get_reservation_info (table_index, reservable_element, reserved_to_job, reserving_job);
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        result^.boolean_value.value := reserved_to_job;

      ELSEIF attribute = 'RESERVING_JOB_IDENTIFICATION' THEN
        cmp$search_peripheral_table (element_descriptor, element_reservation, not_in_configuration,
              table_index, status);
        IF NOT status.normal THEN
          EXIT /main_program/;
        IFEND;
        cmp$get_reservation_info (table_index, reservable_element, reserved_to_job, reserving_job);
        result^.kind := clc$name;
        IF reserved_to_job THEN
          result^.name_value := reserving_job;
        ELSE
          result^.name_value := ' ';
        IFEND;

      ELSEIF attribute = 'RESTORING_DRIVE' THEN
        IF (((element_def^.product_id.product_number = ' $5833') OR
             (element_def^.product_id.product_number = ' $5838') OR
             (element_def^.product_id.product_number = '$47444') OR
             (element_def^.product_id.product_number = ' $5837')) AND
               ((element_def^.product_id.model_number = '1P ') OR
                (element_def^.product_id.model_number = '3P '))) THEN

            cmp$get_parity_status_info (element_name, parity_status, status);
            IF NOT status.normal THEN
              EXIT /main_program/;
            IFEND;
            IF parity_status.off_line_drive_number <> init_offln_drv_num THEN
              result^.kind := clc$boolean;
              result^.boolean_value.kind := clc$true_false_boolean;
              result^.boolean_value.value := parity_status.restoring_drive;
            IFEND;
        IFEND;

      ELSEIF attribute = 'SERIAL_NUMBER' THEN
        result^.kind := clc$integer;
        result^.integer_value.radix := 10;
        result^.integer_value.radix_specified := FALSE;
        clp$convert_string_to_integer (element_info [1].serial_number (1, 6), result^.integer_value, status);

      ELSEIF attribute = 'SITE_INFORMATION' THEN
        IF element_info [1].site_info_string_size > 0 THEN
          NEXT string_p: [element_info [1].site_info_string_size] in work_area;
          element_info [1].selector := cmc$site_information;
          element_info [1].site_information := string_p;
          cmp$get_element_information (element_descriptor, element_info, ignore);
          IF NOT ignore.normal THEN
            EXIT /main_program/;
          IFEND;
          result^.string_value := element_info [1].site_information;
        IFEND;
      ELSEIF attribute = 'SYSTEM_CRITICAL_ELEMENT' THEN
        result^.kind := clc$boolean;
        result^.boolean_value.kind := clc$true_false_boolean;
        result^.boolean_value.value := element_info [1].system_critical_element;

      IFEND;

    END /main_program/;

  PROCEND cmp$$element;

?? OLDTITLE ??
?? NEWTITLE := '  $MASS_STORAGE_CLASS_MEMBERS', EJECT ??

{ PURPOSE:
{   This functions returns a record for each member of the mass storage class
{
{ NOTE:
{   The record returned is of the following SCL type:
{   "member_volume" record
{     element_name: name
{     recorded_vsn: name 1 .. 6
{     volume_available: boolean
{  recend
{

  PROCEDURE [XDCL, #GATE] cmp$$mass_storage_class_members
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);


{   FUNCTION (cmm$$mass_storage_class_members) $mass_storage_class_members (
{     class: name 1 = $required
{  )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
      recend,
    recend := [
    [1,
    [89, 4, 19, 9, 41, 44, 381],
    clc$function, 1, 1, 1, 0, 0, 0, 0, 'CMM$$MASS_STORAGE_CLASS_MEMBERS'], [
    ['CLASS                          ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0
  , 0]],
{ PARAMETER 1
    [[1, 0, clc$name_type], [1, 1]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$class = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

    VAR
      class: dmt$class,
      element_name: cmt$element_name,
      ignore_status: ost$status,
      index: integer,
      lun: iot$logical_unit,
      max_ms_volumes: integer,
      ms_volumes: ^array [1 .. * ] of cmt$mass_storage_volume,
      value: ^clt$data_value;

    status.normal := TRUE;
    {
    { Preset function result to empty list.
    {
    NEXT result IN work_area;
    result^.kind := clc$list;
    result^.element_value := NIL;
    result^.link := NIL;
    result^.generated_via_list_rest := FALSE;
    class := $dmt$class [];

    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
          OR avp$system_displays ()) THEN
      RETURN;
    IFEND;

    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    class := class + $dmt$class [pvt [p$class].value^.name_value];
    cmp$get_ms_volumes (max_ms_volumes);
    PUSH ms_volumes: [1 .. max_ms_volumes];
    cmp$get_ms_volume_info (ms_volumes^);
    value := NIL;
    FOR index := 1 TO max_ms_volumes DO
      IF class <= ms_volumes^ [index].class THEN
        IF value = NIL THEN
          value := result;
        ELSE
          NEXT value^.link IN work_area;
          value^.link^.kind := clc$list;
          value^.link^.generated_via_list_rest := FALSE;
          value := value^.link;
          value^.link := NIL;
        IFEND;

        cmp$get_unit_number_via_vsn (ms_volumes^ [index].recorded_vsn, lun, ignore_status);
        IF NOT ignore_status.normal THEN
          RETURN;
        IFEND;

        cmp$get_element_name_via_lun (lun, element_name, ignore_status);
        IF NOT ignore_status.normal THEN
          RETURN;
        IFEND;

        NEXT value^.element_value IN work_area;
        value^.element_value^.kind := clc$record;
        NEXT value^.element_value^.field_values: [1 .. 3] IN work_area;
        value^.element_value^.field_values^ [1].name := 'ELEMENT_NAME';
        NEXT value^.element_value^.field_values^ [1].value IN work_area;
        value^.element_value^.field_values^ [1].value^.kind := clc$name;
        value^.element_value^.field_values^ [1].value^.name_value := element_name;
        value^.element_value^.field_values^ [2].name := 'RECORDED_VSN';
        NEXT value^.element_value^.field_values^ [2].value IN work_area;
        value^.element_value^.field_values^ [2].value^.kind := clc$name;
        value^.element_value^.field_values^ [2].value^.name_value := ms_volumes^ [index].recorded_vsn;
        value^.element_value^.field_values^ [3].name := 'VOLUME_AVAILABLE';
        NEXT value^.element_value^.field_values^ [3].value IN work_area;
        value^.element_value^.field_values^ [3].value^.kind := clc$boolean;
        value^.element_value^.field_values^ [3].value^.boolean_value.kind := clc$true_false_boolean;
        value^.element_value^.field_values^ [3].value^.boolean_value.value :=
              volume_available (ms_volumes^ [index].recorded_vsn);
        value^.generated_via_list_rest := FALSE;
      IFEND;
    FOREND;

  PROCEND cmp$$mass_storage_class_members;

?? OLDTITLE ??
?? NEWTITLE := '  $PHYSICAL_ADDRESS', EJECT ??

{ PURPOSE:
{   This function returns the physical address of an element, given its upline element and the element itself.

  PROCEDURE [XDCL, #GATE] cmp$$physical_address
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);

{ FUNCTION (cmm$$physical_address) $physical_address (
{   upline_element: name = $required
{   downline_element: name = $required
{   iou: name = IOU0
{   )

?? PUSH (LISTEXT := ON) ??

    VAR
      pdt: [STATIC, READ, cls$declaration_section] record
        header: clt$pdt_header,
        names: array [1 .. 3] of clt$pdt_parameter_name,
        parameters: array [1 .. 3] of clt$pdt_parameter,
        type1: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        type2: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
        type3: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
          default_value: string (4),
        recend,
      recend := [[1, [88, 11, 2, 12, 34, 56, 789], clc$function, 3, 3, 2, 0, 0, 0, 0,
            'CMM$$PHYSICAL_ADDRESS'], [['DOWNLINE_ELEMENT               ', clc$nominal_entry, 2],
            ['IOU                            ', clc$nominal_entry, 3],
            ['UPLINE_ELEMENT                 ', clc$nominal_entry, 1]], [

{ UPLINE_ELEMENT

      [3, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0, 0],

{ DOWNLINE_ELEMENT

      [1, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$required_parameter, 0, 0],

{ IOU

      [2, clc$normal_usage_entry, clc$non_secure_parameter,
            $clt$parameter_spec_methods [clc$specify_positionally], clc$pass_by_value,
            clc$immediate_evaluation, clc$standard_parameter_checking, 5, clc$optional_default_parameter, 0,
            4]],

{ UPLINE_ELEMENT

      [[1, 0, clc$name_type], [1, osc$max_name_size]],

{ DOWNLINE_ELEMENT

      [[1, 0, clc$name_type], [1, osc$max_name_size]],

{ IOU

      [[1, 0, clc$name_type], [1, osc$max_name_size], 'IOU0']];

?? POP ??

    CONST
      p$upline_element = 1,
      p$downline_element = 2,
      p$iou = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    VAR
      downline_element: cmt$element_name,
      element: ^cmt$element_definition,
      iou_name: cmt$element_name,
      pen: cmt$physical_equipment_number,
      pun: cmt$physical_unit_number,
      upline_element: cmt$element_name;

    status.normal := TRUE;

  /main_program/
    BEGIN

{ Preset result = -1 so SOMETHING will be returned no matter what else goes wrong...

      NEXT result IN work_area;
      result^.kind := clc$integer;
      result^.integer_value.radix := 10;
      result^.integer_value.radix_specified := FALSE;
      result^.integer_value.value := -1;

      IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
              OR avp$system_displays ()) THEN
        EXIT /main_program/;
      IFEND;
      clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      downline_element := pvt [p$downline_element].value^.name_value;
      iou_name := pvt [p$iou].value^.name_value;
      upline_element := pvt [p$upline_element].value^.name_value;

      cmp$pc_get_element (upline_element, iou_name, element, status);
      IF NOT status.normal THEN
        status.normal := TRUE;
        EXIT /main_program/;
      IFEND;

      CASE element^.element_type OF
      = cmc$controller_element =
        FOR pun := LOWERVALUE (cmt$physical_unit_number) TO UPPERVALUE (cmt$physical_unit_number) DO
          IF element^.controller.connection.unit [pun].configured THEN
            IF element^.controller.connection.unit [pun].element_name = downline_element THEN
              result^.integer_value.value := pun;
              EXIT /main_program/;
            IFEND;
          IFEND;
        FOREND;

      = cmc$data_channel_element =
        FOR pen := LOWERVALUE (cmt$physical_equipment_number) TO UPPERVALUE (cmt$physical_equipment_number) DO
          IF element^.data_channel.connection.equipment [pen].configured THEN
            IF element^.data_channel.connection.equipment [pen].element_name = downline_element THEN
              result^.integer_value.value := pen;
              EXIT /main_program/;
            IFEND;
          IFEND;
        FOREND;

      ELSE
        ;
      CASEND;

    END /main_program/;
  PROCEND cmp$$physical_address;

?? OLDTITLE ??
?? NEWTITLE := '  $STORAGE_DEVICE_NAME ', EJECT ??

{ PURPOSE:
{   This function returns the element name of a storage device element given its recorded vsn.

  PROCEDURE [XDCL, #GATE] cmp$$storage_device_name
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);

{  FUNCTION (cmm$$storage_device) $storage_device (
{    recorded_vsn: name 1..6 = $required
{    )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 1] of clt$pdt_parameter_name,
      parameters: array [1 .. 1] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$name_type_qualifier,
      recend,
    recend := [
    [1,
    [89, 8, 25, 9, 37, 51, 266],
    clc$function, 1, 1, 1, 0, 0, 0, 0, 'CMM$$STORAGE_DEVICE'], [
    ['RECORDED_VSN                   ',clc$nominal_entry, 1]],
    [
{ PARAMETER 1
    [1, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation,
  clc$standard_parameter_checking, 5, clc$required_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$name_type], [1, 6]]];

?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$recorded_vsn = 1;

    VAR
      pvt: array [1 .. 1] of clt$parameter_value;

    VAR
      element: ^cmt$element_definition,
      ignore: ost$status,
      lun: iot$logical_unit,
      recorded_vsn: rmt$recorded_vsn;

    status.normal := TRUE;

  /main_program/
    BEGIN

{ Preset empty string so SOMETHING will be returned no matter what else goes wrong...

      NEXT result IN work_area;
      result^.kind := clc$string;
      NEXT result^.string_value: [0] IN work_area;

      IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
              OR avp$system_displays ()) THEN
        EXIT /main_program/;
      IFEND;
      clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
      IF NOT status.normal THEN
        EXIT /main_program/;
      IFEND;

      recorded_vsn := pvt [p$recorded_vsn].value^.name_value;
      cmp$get_unit_number_via_vsn (recorded_vsn, lun, ignore);
      IF NOT ignore.normal THEN
        EXIT /main_program/;
      IFEND;
      cmp$pc_get_logical_unit (lun, element, ignore);
      IF NOT ignore.normal THEN
        EXIT /main_program/;
      IFEND;

      result^.kind := clc$name;
      result^.name_value := ' ';
      result^.name_value := element^.element_name;

    END /main_program/;

  PROCEND cmp$$storage_device_name;

?? OLDTITLE ??
?? NEWTITLE := '   $SYSTEM_SET_NAME', EJECT ??

{ PURPOSE:
{   This function provides the name of the system set.

  PROCEDURE [XDCL, #GATE] cmp$$system_set_name
    (    parameter_list: clt$parameter_list;
     VAR work_area: ^clt$work_area;
     VAR result: ^clt$data_value;
     VAR status: ost$status);


{  FUNCTION (cmm$$system_set_name) $system_set_name (
{ )

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
    recend := [
    [1,
    [89, 4, 19, 12, 33, 10, 583],
    clc$function, 0, 0, 0, 0, 0, 0, 0, 'CMM$$SYSTEM_SET_NAME']];

?? FMT (FORMAT := ON) ??
?? POP ??

    status.normal := TRUE;
    NEXT result IN work_area;
    result^.kind := clc$name;
    result^.name_value := osc$null_name;
    IF NOT (avp$configuration_administrator () OR avp$removable_media_operator ()
         OR avp$system_displays ()) THEN
      RETURN;
    IFEND;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, NIL, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    result^.name_value := stv$system_set_name;

  PROCEND cmp$$system_set_name;
?? TITLE := '[inline] VOLUME_AVAILABLE', EJECT ??

  FUNCTION [INLINE] volume_available
    (    recorded_vsn: rmt$recorded_vsn): boolean;

    VAR
      avt_index: integer,
      entry_p: ^dmt$active_volume_table_entry;

  /avt_loop/
    FOR avt_index := LOWERBOUND (dmv$active_volume_table.table_p^)
          TO UPPERBOUND (dmv$active_volume_table.table_p^) DO
      entry_p := ^dmv$active_volume_table.table_p^ [avt_index];
      IF entry_p^.entry_available OR (entry_p^.mass_storage.recorded_vsn <> recorded_vsn) THEN
        CYCLE /avt_loop/; {----->
      IFEND;

      volume_available := (NOT entry_p^.mass_storage.volume_unavailable);
      RETURN; {----->
    FOREND /avt_loop/;

    volume_available := FALSE;

  FUNCEND volume_available;
?? OLDTITLE, OLDTITLE ??
MODEND cmm$lcu_functions;
