?? LEFT := 1, RIGHT := 110 ??
MODULE pfm$move_object;

?? PUSH (LISTEXT := ON) ??
*copyc cle$ecc_file_reference
*copyc cme$logical_configuration_mgr
*copyc cme$logical_configuration_utl
*copyc cme$reserve_element
*copyc dmt$subfile_index
*copyc fst$goi_object_information
*copyc fst$goi_object_list
*copyc oss$job_paged_literal
*copyc pft$complete_path
*copyc pfe$error_condition_codes
*copyc pfe$internal_error_conditions
*copyc pft$move_object_info
*copyc pft$volume_list
*copyc rme$request_mass_storage
?? POP ??

*copyc avp$family_administrator
*copyc avp$system_administrator
*copyc clp$build_path_subtitle
*copyc clp$convert_file_ref_to_string
*copyc clp$convert_integer_to_rjstring
*copyc clp$count_list_elements
*copyc clp$close_display
*copyc clp$convert_cyc_ref_to_cyc_sel
*copyc clp$convert_integer_to_string
*copyc clp$convert_cyc_ref_to_cyc_sel
*copyc clp$evaluate_file_reference
*copyc clp$horizontal_tab_display
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc clp$put_partial_display
*copyc clp$evaluate_parameters
*copyc clv$user_identification
*copyc cmp$get_element_state_via_lun
*copyc cmp$get_ms_status_via_lun
*copyc cmp$get_ms_volumes
*copyc cmp$get_ms_volume_info
*copyc dmp$utility_flush_logs_r3
*copyc fsp$build_file_ref_from_elems
*copyc fsp$convert_fs_structure_to_pf
*copyc fsp$evaluate_file_reference
*copyc i#current_sequence_position
*copyc mmp$create_scratch_segment
*copyc mmp$delete_scratch_segment
*copyc osp$append_status_parameter
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$format_message
*copyc osp$set_status_abnormal
*copyc pfp$convert_pft$path_to_fs_path
*copyc pfp$get_families_in_set
*copyc pfp$get_family_set
*copyc pfp$get_volumes_in_set
*copyc pfp$get_volumes_set_name
*copyc pfp$log_ascii
*copyc pfp$no_space_movc_dest_volumes
*copyc pfp$r3_get_move_obj_device_info
*copyc pfp$r3_get_object_information
*copyc pfp$r3_physically_move_catalog
*copyc pfp$r3_physically_move_cycle
*copyc pmp$format_compact_date
*copyc pmp$format_compact_time
*copyc pmp$get_compact_date_time
*copyc pmp$get_microsecond_clock
*copyc pmp$get_task_cp_time
*copyc pmp$log_ascii

?? TITLE := 'Global Declarations Declared by this Module', EJECT ??

  CONST
    class_tab = 24,
    data_residence_tab = 50,
    volume_tab = 30,
    integer_value_tab = 40,
    path_tab = 2,
    move_data_tab = 5,
    old_subfile_vsn_tab = 14,
    old_subfile_length_tab = 29,
    new_subfile_vsn_tab = 53,
    new_subfile_length_tab = 68,
    title_tab = 3,
    subheader_tab = header_tab + 2,
    header_tab = 5;

  CONST
    subfile_header = 'Original Volume     Subfile Length          New Volume     Subfile Length';

  VAR
    catalog_information_request: [STATIC, READ, oss$job_paged_literal] fst$goi_information_request :=
          [[fsc$specific_depth, 1], $fst$goi_object_info_requests
          [fsc$goi_catalog_identity, fsc$goi_catalog_device_info, fsc$goi_catalog_info, fsc$goi_catalog_size,
          fsc$goi_catalog_object_list, fsc$goi_file_object_list, fsc$goi_file_identity, fsc$goi_file_info,
          fsc$goi_cycle_object_list, fsc$goi_cycle_identity, fsc$goi_archive_info, fsc$goi_cycle_device_info,
          fsc$goi_cycle_info, fsc$goi_cycle_size]],
    prohibited_classes: [STATIC, READ, oss$job_paged_literal] dmt$class := ['A', 'C', 'N', 'Q'];


?? OLDTITLE ??
?? NEWTITLE := '[XDCL] pfp$move_classes_command', EJECT ??
{ PURPOSE:
{   This is the command processor for the MOVE_CLASSES command.
{

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

{ PROCEDURE move_classes, move_class, movc (
{   catalogs, catalog, c: (BY_NAME) list of file = $optional
{   destination_volumes, destination_volume, dv: (BY_NAME) list of name 1..6 = $optional
{   files, file, f: (BY_NAME) list of file = $optional
{   hierarchy, h: (BY_NAME) any of
{       key
{         set
{       keyend
{       file
{     anyend = set
{   mass_storage_classes, mass_storage_class, msc: (BY_NAME) any of
{       key
{         all
{       keyend
{       list of key
{         (nosve_defined, nd)
{         (site_defined, sd)
{         (system_catalogs, sc)
{         (system_objects, so)
{         (system_permanent_files, system_files, spf, sf)
{         (system_products, sp)
{         (user_catalogs, uc)
{         (user_objects, uo)
{         (user_permanent_files, upf, user_files, uf)
{       keyend
{       list 1..25 of name 1..1
{     anyend = $required
{   megabytes, mb, m: (BY_NAME) integer 1..100000 = $optional
{   output, o: (BY_NAME) file = $output
{   perform_move, pm: (BY_NAME) boolean = $confirm TRUE
{   release_mass_storage, rms: (BY_NAME) any of
{       boolean
{       key
{         (when_space_unavailable, wsu)
{       keyend
{     anyend = false
{   source_volumes, source_volume, sv: (BY_NAME) list of name 1..6 = $optional
{   volume_overflow_allowed, voa: (BY_NAME) boolean = TRUE
{   wait, w: (BY_NAME) boolean = TRUE
{   status)

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

  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 31] of clt$pdt_parameter_name,
      parameters: array [1 .. 13] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
        qualifier: clt$list_type_qualifier_v2,
        element_type_spec: record
          header: clt$type_specification_header,
        recend,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$list_type_qualifier_v2,
        element_type_spec: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
      recend,
      type3: record
        header: clt$type_specification_header,
        qualifier: clt$list_type_qualifier_v2,
        element_type_spec: record
          header: clt$type_specification_header,
        recend,
      recend,
      type4: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 1] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
        recend,
        default_value: string (3),
      recend,
      type5: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 1] of clt$keyword_specification,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$list_type_qualifier_v2,
          element_type_spec: record
            header: clt$type_specification_header,
            qualifier: clt$keyword_type_qualifier,
            keyword_specs: array [1 .. 22] of clt$keyword_specification,
          recend,
        recend,
        type_size_3: clt$type_specification_size,
        element_type_spec_3: record
          header: clt$type_specification_header,
          qualifier: clt$list_type_qualifier_v2,
          element_type_spec: record
            header: clt$type_specification_header,
            qualifier: clt$name_type_qualifier,
          recend,
        recend,
      recend,
      type6: record
        header: clt$type_specification_header,
        qualifier: clt$integer_type_qualifier,
      recend,
      type7: record
        header: clt$type_specification_header,
        default_value: string (7),
      recend,
      type8: record
        header: clt$type_specification_header,
        default_value: string (4),
      recend,
      type9: record
        header: clt$type_specification_header,
        qualifier: clt$union_type_qualifier,
        type_size_1: clt$type_specification_size,
        element_type_spec_1: record
          header: clt$type_specification_header,
        recend,
        type_size_2: clt$type_specification_size,
        element_type_spec_2: record
          header: clt$type_specification_header,
          qualifier: clt$keyword_type_qualifier,
          keyword_specs: array [1 .. 2] of clt$keyword_specification,
        recend,
        default_value: string (5),
      recend,
      type10: record
        header: clt$type_specification_header,
        qualifier: clt$list_type_qualifier_v2,
        element_type_spec: record
          header: clt$type_specification_header,
          qualifier: clt$name_type_qualifier,
        recend,
      recend,
      type11: record
        header: clt$type_specification_header,
        default_value: string (4),
      recend,
      type12: record
        header: clt$type_specification_header,
        default_value: string (4),
      recend,
      type13: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [93, 1, 13, 12, 37, 55, 126],
    clc$command, 31, 13, 1, 0, 0, 0, 13, ''], [
    ['C                              ',clc$abbreviation_entry, 1],
    ['CATALOG                        ',clc$alias_entry, 1],
    ['CATALOGS                       ',clc$nominal_entry, 1],
    ['DESTINATION_VOLUME             ',clc$alias_entry, 2],
    ['DESTINATION_VOLUMES            ',clc$nominal_entry, 2],
    ['DV                             ',clc$abbreviation_entry, 2],
    ['F                              ',clc$abbreviation_entry, 3],
    ['FILE                           ',clc$alias_entry, 3],
    ['FILES                          ',clc$nominal_entry, 3],
    ['H                              ',clc$abbreviation_entry, 4],
    ['HIERARCHY                      ',clc$nominal_entry, 4],
    ['M                              ',clc$abbreviation_entry, 6],
    ['MASS_STORAGE_CLASS             ',clc$alias_entry, 5],
    ['MASS_STORAGE_CLASSES           ',clc$nominal_entry, 5],
    ['MB                             ',clc$alias_entry, 6],
    ['MEGABYTES                      ',clc$nominal_entry, 6],
    ['MSC                            ',clc$abbreviation_entry, 5],
    ['O                              ',clc$abbreviation_entry, 7],
    ['OUTPUT                         ',clc$nominal_entry, 7],
    ['PERFORM_MOVE                   ',clc$nominal_entry, 8],
    ['PM                             ',clc$abbreviation_entry, 8],
    ['RELEASE_MASS_STORAGE           ',clc$nominal_entry, 9],
    ['RMS                            ',clc$abbreviation_entry, 9],
    ['SOURCE_VOLUME                  ',clc$alias_entry, 10],
    ['SOURCE_VOLUMES                 ',clc$nominal_entry, 10],
    ['STATUS                         ',clc$nominal_entry, 13],
    ['SV                             ',clc$abbreviation_entry, 10],
    ['VOA                            ',clc$abbreviation_entry, 11],
    ['VOLUME_OVERFLOW_ALLOWED        ',clc$nominal_entry, 11],
    ['W                              ',clc$abbreviation_entry, 12],
    ['WAIT                           ',clc$nominal_entry, 12]],
    [
{ PARAMETER 1
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 19, clc$optional_parameter,
  0, 0],
{ PARAMETER 2
    [5, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 21, clc$optional_parameter,
  0, 0],
{ PARAMETER 3
    [9, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 19, clc$optional_parameter,
  0, 0],
{ PARAMETER 4
    [11, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 67,
  clc$optional_default_parameter, 0, 3],
{ PARAMETER 5
    [14, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 926,
  clc$required_parameter, 0, 0],
{ PARAMETER 6
    [16, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 20, clc$optional_parameter,
  0, 0],
{ PARAMETER 7
    [19, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 7],
{ PARAMETER 8
    [20, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$confirm_default_parameter, 0, 4],
{ PARAMETER 9
    [22, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 104,
  clc$optional_default_parameter, 0, 5],
{ PARAMETER 10
    [25, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 21, clc$optional_parameter,
  0, 0],
{ PARAMETER 11
    [29, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 4],
{ PARAMETER 12
    [31, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_default_parameter, 0, 4],
{ PARAMETER 13
    [26, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$list_type], [3, 1, clc$max_list_size, 0, FALSE, FALSE],
      [[1, 0, clc$file_type]]
    ],
{ PARAMETER 2
    [[1, 0, clc$list_type], [5, 1, clc$max_list_size, 0, FALSE, FALSE],
      [[1, 0, clc$name_type], [1, 6]]
    ],
{ PARAMETER 3
    [[1, 0, clc$list_type], [3, 1, clc$max_list_size, 0, FALSE, FALSE],
      [[1, 0, clc$file_type]]
    ],
{ PARAMETER 4
    [[1, 0, clc$union_type], [[clc$file_type, clc$keyword_type],
    FALSE, 2],
    44, [[1, 0, clc$keyword_type], [1], [
      ['SET                            ', clc$nominal_entry, clc$normal_usage_entry, 1]]
      ],
    3, [[1, 0, clc$file_type]]
    ,
    'set'],
{ PARAMETER 5
    [[1, 0, clc$union_type], [[clc$keyword_type, clc$list_type],
    FALSE, 3],
    44, [[1, 0, clc$keyword_type], [1], [
      ['ALL                            ', clc$nominal_entry, clc$normal_usage_entry, 1]]
      ],
    837, [[1, 0, clc$list_type], [821, 1, clc$max_list_size, 0, FALSE, FALSE],
        [[1, 0, clc$keyword_type], [22], [
        ['ND                             ', clc$abbreviation_entry, clc$normal_usage_entry, 1],
        ['NOSVE_DEFINED                  ', clc$nominal_entry, clc$normal_usage_entry, 1],
        ['SC                             ', clc$abbreviation_entry, clc$normal_usage_entry, 3],
        ['SD                             ', clc$abbreviation_entry, clc$normal_usage_entry, 2],
        ['SF                             ', clc$abbreviation_entry, clc$normal_usage_entry, 5],
        ['SITE_DEFINED                   ', clc$nominal_entry, clc$normal_usage_entry, 2],
        ['SO                             ', clc$abbreviation_entry, clc$normal_usage_entry, 4],
        ['SP                             ', clc$abbreviation_entry, clc$normal_usage_entry, 6],
        ['SPF                            ', clc$alias_entry, clc$normal_usage_entry, 5],
        ['SYSTEM_CATALOGS                ', clc$nominal_entry, clc$normal_usage_entry, 3],
        ['SYSTEM_FILES                   ', clc$alias_entry, clc$normal_usage_entry, 5],
        ['SYSTEM_OBJECTS                 ', clc$nominal_entry, clc$normal_usage_entry, 4],
        ['SYSTEM_PERMANENT_FILES         ', clc$nominal_entry, clc$normal_usage_entry, 5],
        ['SYSTEM_PRODUCTS                ', clc$nominal_entry, clc$normal_usage_entry, 6],
        ['UC                             ', clc$abbreviation_entry, clc$normal_usage_entry, 7],
        ['UF                             ', clc$abbreviation_entry, clc$normal_usage_entry, 9],
        ['UO                             ', clc$abbreviation_entry, clc$normal_usage_entry, 8],
        ['UPF                            ', clc$alias_entry, clc$normal_usage_entry, 9],
        ['USER_CATALOGS                  ', clc$nominal_entry, clc$normal_usage_entry, 7],
        ['USER_FILES                     ', clc$alias_entry, clc$normal_usage_entry, 9],
        ['USER_OBJECTS                   ', clc$nominal_entry, clc$normal_usage_entry, 8],
        ['USER_PERMANENT_FILES           ', clc$nominal_entry, clc$normal_usage_entry, 9]]
        ]
      ],
    21, [[1, 0, clc$list_type], [5, 1, 25, 0, FALSE, FALSE],
        [[1, 0, clc$name_type], [1, 1]]
      ]
    ],
{ PARAMETER 6
    [[1, 0, clc$integer_type], [1, 100000, 10]],
{ PARAMETER 7
    [[1, 0, clc$file_type],
    '$output'],
{ PARAMETER 8
    [[1, 0, clc$boolean_type],
    'TRUE'],
{ PARAMETER 9
    [[1, 0, clc$union_type], [[clc$boolean_type, clc$keyword_type],
    FALSE, 2],
    3, [[1, 0, clc$boolean_type]],
    81, [[1, 0, clc$keyword_type], [2], [
      ['WHEN_SPACE_UNAVAILABLE         ', clc$nominal_entry, clc$normal_usage_entry, 1],
      ['WSU                            ', clc$abbreviation_entry, clc$normal_usage_entry, 1]]
      ]
    ,
    'false'],
{ PARAMETER 10
    [[1, 0, clc$list_type], [5, 1, clc$max_list_size, 0, FALSE, FALSE],
      [[1, 0, clc$name_type], [1, 6]]
    ],
{ PARAMETER 11
    [[1, 0, clc$boolean_type],
    'TRUE'],
{ PARAMETER 12
    [[1, 0, clc$boolean_type],
    'TRUE'],
{ PARAMETER 13
    [[1, 0, clc$status_type]]];

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

    CONST
      p$catalogs = 1,
      p$destination_volumes = 2,
      p$files = 3,
      p$hierarchy = 4,
      p$mass_storage_classes = 5,
      p$megabytes = 6,
      p$output = 7,
      p$perform_move = 8,
      p$release_mass_storage = 9,
      p$source_volumes = 10,
      p$volume_overflow_allowed = 11,
      p$wait = 12,
      p$status = 13;

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

?? NEWTITLE := 'abort_handler', EJECT ??

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           ignore_condition_information: ^pmt$condition_information;
           ignore_save_area: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      VAR
        local_status: ost$status;

      IF display_opened THEN
        display_summary (move_object_info_p^, display_control, local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;

        clp$close_display (display_control, local_status);
        IF status.normal AND (NOT local_status.normal) THEN
          status := local_status;
        IFEND;

        display_opened := FALSE;
        #SPOIL (display_opened);
      IFEND;

    PROCEND abort_handler;

?? OLDTITLE, EJECT ??

    VAR
      ch: 'A' .. 'Z',
      current_value: ^clt$data_value,
      cl_cycle_selector: clt$cycle_selector,
      cycle_number: fst$cycle_number,
      default_movement_statistics: pft$movement_statistics,
      default_ring_attributes: amt$ring_attributes,
      dest_volume_count: integer,
      display_control: clt$display_control,
      display_opened: boolean,
      element_count: integer,
      evaluated_file_reference: fst$evaluated_file_reference,
      family_catalog_info_p: ^fst$goi_object,
      family_catalog_reference: fst$path,
      family_found: boolean,
      family_object_info_p: ^fst$goi_object_information,
      i: integer,
      ignore_status: ost$status,
      index1: integer,
      index2: integer,
      j: integer,
      local_status: ost$status,
      master_catalog_array_p: ^fst$goi_object_list,
      master_catalog_path: array [1 .. 2] of pft$name,
      move_object_info_p: ^pft$move_object_info,
      number_of_volumes_in_set: integer,
      object_index: integer,
      object_info_p: ^SEQ ( * ),
      object_segment_pointer: amt$segment_pointer,
      p_cycle_number: ^fst$cycle_number,
      p_path: ^pft$path,
      set_name: ost$name,
      set_volume_list_p: ^pft$mo_volume_list,
      source_volume_count: integer,
      sub_object_info_p: ^SEQ ( * ),
      temp_volume_count: integer,
      temp_volume_list_p: ^pft$volume_list,
      traverse_hierarchy: boolean,
      traverse_set: boolean,
      user_id: ost$user_identification,
      user_name: ost$user_name,
      volume_available: boolean,
      volume_found: boolean,
      volume_list_p: ^pft$volume_list,
      volume_list_size: ost$positive_integers;

    IF (NOT avp$family_administrator ()) AND (NOT avp$system_administrator ()) THEN
      osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$not_system_administrator,
            'MOVE_CLASSES', status);
      RETURN;
    IFEND;

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

    IF (pvt [p$hierarchy].specified) AND (pvt [p$files].specified OR pvt [p$catalogs].specified) THEN
      osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_parameter_conflict_2,
            'HIERARCHY', status);
      RETURN;
    IFEND;

    IF (pvt [p$megabytes].specified) AND (pvt [p$files].specified OR pvt [p$catalogs].specified) THEN
      osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_parameter_conflict_2,
            'MEGABYTES', status);
      RETURN;
    IFEND;

    default_movement_statistics.abnormal_status := 0;
    default_movement_statistics.bytes_moved := 0;
    default_movement_statistics.bytes_released := 0;
    default_movement_statistics.cycle_busy := 0;
    default_movement_statistics.cycles_released := 0;
    default_movement_statistics.insufficient_space := 0;
    default_movement_statistics.no_available_space := 0;
    default_movement_statistics.objects_moved := 0;
    default_movement_statistics.objects_not_moved := 0;
    default_movement_statistics.unrecovered_read_error := 0;

    PUSH move_object_info_p;

    FOR ch := 'A' TO 'Z' DO
      move_object_info_p^.class_statistics [ch] := default_movement_statistics;
    FOREND;

    move_object_info_p^.dest_volume_list_p := NIL;
    move_object_info_p^.mass_storage_class := $dmt$class [];
    move_object_info_p^.move_bytes_threshold := 0;
    move_object_info_p^.overall_statistics := default_movement_statistics;
    move_object_info_p^.perform_move := TRUE;
    move_object_info_p^.performance_statistics.catalog_count := 0;
    move_object_info_p^.performance_statistics.cycle_count := 0;
    move_object_info_p^.performance_statistics.file_count := 0;
    move_object_info_p^.release_mass_storage := pfc$never;
    move_object_info_p^.set_name := osc$null_name;
    move_object_info_p^.set_volume_list_p := NIL;
    move_object_info_p^.source_volume_list_p := NIL;
    move_object_info_p^.update_available_space_total := 0;
    move_object_info_p^.volume_overflow_allowed := TRUE;
    move_object_info_p^.wait := TRUE;

    pmp$get_compact_date_time (move_object_info_p^.performance_statistics.initial_date_time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$get_microsecond_clock (move_object_info_p^.performance_statistics.initial_microsecond_clock, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$get_task_cp_time (move_object_info_p^.performance_statistics.initial_task_cp_time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    volume_list_size := 2 * UPPERVALUE(dmt$subfile_index) * #SIZE(pft$subfile);
    PUSH move_object_info_p^.move_status.volume_list_storage_p: [[REP volume_list_size OF cell]];
    RESET move_object_info_p^.move_status.volume_list_storage_p;
    move_object_info_p^.move_status.move_successful := FALSE;
    move_object_info_p^.move_status.new_subfile_list_p := NIL;
    move_object_info_p^.move_status.old_subfile_list_p := NIL;
    move_object_info_p^.move_status.reason_for_move_failure := pfc$unexpected_abort;

    {
    { Get set name to validate all volumes, files and catalogs.
    {
    IF pvt [p$source_volumes].specified THEN
      pfp$get_volumes_set_name (pvt [p$source_volumes].value^.element_value^.name_value (1, 6), set_name,
            status);
    ELSEIF pvt [p$destination_volumes].specified THEN
      pfp$get_volumes_set_name (pvt [p$destination_volumes].value^.element_value^.name_value (1, 6),
            set_name, status);
    ELSE
      osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_parameter_conflict_1, ' ', status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    move_object_info_p^.set_name := set_name;

    number_of_volumes_in_set := 10;
    REPEAT
      PUSH volume_list_p: [1 .. number_of_volumes_in_set];
      pfp$get_volumes_in_set (set_name, volume_list_p^, number_of_volumes_in_set, status);
    UNTIL (NOT status.normal OR (number_of_volumes_in_set <= UPPERBOUND (volume_list_p^)));
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    PUSH move_object_info_p^.set_volume_list_p: [1 .. number_of_volumes_in_set];
    FOR i := 1 TO number_of_volumes_in_set DO
      move_object_info_p^.set_volume_list_p^ [i].recorded_vsn := volume_list_p^ [i];
    FOREND;
    set_volume_list_p := move_object_info_p^.set_volume_list_p;

    initialize_set_volume_list (move_object_info_p^.set_volume_list_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF pvt [p$mass_storage_classes].specified THEN
      IF pvt [p$mass_storage_classes].value^.kind = clc$keyword THEN
        IF pvt [p$mass_storage_classes].value^.keyword_value = 'ALL' THEN
          move_object_info_p^.mass_storage_class := -$dmt$class [];
          move_object_info_p^.mass_storage_class :=
                move_object_info_p^.mass_storage_class - prohibited_classes;
        IFEND;
      ELSE
        current_value := pvt [p$mass_storage_classes].value;
        WHILE (current_value <> NIL) AND (current_value^.element_value <> NIL) DO
          IF current_value^.element_value^.kind = clc$keyword THEN
            IF current_value^.element_value^.keyword_value = 'ALL' THEN
              move_object_info_p^.mass_storage_class := -$dmt$class [];
              move_object_info_p^.mass_storage_class :=
                    move_object_info_p^.mass_storage_class - prohibited_classes;
            ELSEIF current_value^.element_value^.keyword_value = 'NOSVE_DEFINED' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['J', 'K', 'L', 'M', 'P'];
            ELSEIF current_value^.element_value^.keyword_value = 'SITE_DEFINED' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['U', 'V', 'W', 'X', 'Y', 'Z'];
            ELSEIF current_value^.element_value^.keyword_value = 'SYSTEM_CATALOGS' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['J'];
            ELSEIF current_value^.element_value^.keyword_value = 'SYSTEM_PERMANENT_FILES' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['K', 'P'];
            ELSEIF current_value^.element_value^.keyword_value = 'SYSTEM_PRODUCTS' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['P'];
            ELSEIF current_value^.element_value^.keyword_value = 'USER_CATALOGS' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['L'];
            ELSEIF current_value^.element_value^.keyword_value = 'USER_PERMANENT_FILES' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['M'];
            ELSEIF current_value^.element_value^.keyword_value = 'SYSTEM_OBJECTS' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['J', 'K', 'P'];
            ELSEIF current_value^.element_value^.keyword_value = 'USER_OBJECTS' THEN
              move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                    $dmt$class ['L', 'M'];
            ELSE
            IFEND;
          ELSE
            move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class +
                  $dmt$class [current_value^.element_value^.name_value (1)];
          IFEND;
          current_value := current_value^.link;
        WHILEND;
      IFEND;
    ELSE
      move_object_info_p^.mass_storage_class := -$dmt$class [];
      move_object_info_p^.mass_storage_class := move_object_info_p^.mass_storage_class - prohibited_classes;
    IFEND;

    IF pvt [p$perform_move].specified THEN
      move_object_info_p^.perform_move := pvt [p$perform_move].value^.boolean_value.value;
    ELSE
      move_object_info_p^.perform_move := TRUE;
    IFEND;

    IF pvt [p$source_volumes].specified THEN
      PUSH move_object_info_p^.source_volume_list_p:
            [1 .. clp$count_list_elements (pvt [p$source_volumes].value)];
      current_value := pvt [p$source_volumes].value;
      element_count := 0;

      WHILE (current_value <> NIL) AND (current_value^.element_value <> NIL) DO
        element_count := element_count + 1;
        volume_found := FALSE;
        volume_available := FALSE;

        FOR i := 1 TO UPPERBOUND (set_volume_list_p^) DO
          IF current_value^.element_value^.name_value (1, 6) = set_volume_list_p^ [i].recorded_vsn THEN
            volume_found := TRUE;
            volume_available := set_volume_list_p^ [i].available;
            move_object_info_p^.source_volume_list_p^ [element_count] := ^set_volume_list_p^ [i];
            set_volume_list_p^ [i].volume_type := pfc$source_volume;
          IFEND;
        FOREND;

        IF NOT volume_found THEN
          osp$set_status_abnormal (rmc$resource_management_id, rme$vsn_not_part_of_set,
                current_value^.element_value^.name_value (1, 6), status);
          osp$append_status_parameter (osc$status_parameter_delimiter, move_object_info_p^.set_name,
                status);
          RETURN;
        IFEND;

        IF NOT volume_available THEN
          osp$set_status_abnormal (rmc$resource_management_id, pfe$movc_volume_unavailable,
                'SOURCE_VOLUME', status);
          osp$append_status_parameter (osc$status_parameter_delimiter,
                current_value^.element_value^.name_value (1, 6), status);
          RETURN;
        IFEND;

        current_value := current_value^.link;
      WHILEND;
    IFEND;

    IF pvt [p$destination_volumes].specified THEN
      PUSH move_object_info_p^.dest_volume_list_p:
            [1 .. clp$count_list_elements (pvt [p$destination_volumes].value)];
      current_value := pvt [p$destination_volumes].value;
      element_count := 0;

      WHILE (current_value <> NIL) AND (current_value^.element_value <> NIL) DO
        element_count := element_count + 1;
        volume_found := FALSE;
        volume_available := FALSE;

        FOR i := 1 TO UPPERBOUND (set_volume_list_p^) DO
          IF current_value^.element_value^.name_value (1, 6) = set_volume_list_p^ [i].recorded_vsn THEN
            volume_found := TRUE;
            volume_available := set_volume_list_p^ [i].available;
            move_object_info_p^.dest_volume_list_p^ [element_count] := ^set_volume_list_p^ [i];
            IF set_volume_list_p^ [i].volume_type = pfc$source_volume THEN
              osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$redundant_volume_spec,
                    current_value^.element_value^.name_value (1, 6), status);
              RETURN;
            IFEND;
            set_volume_list_p^ [i].volume_type := pfc$destination_volume;
            IF NOT move_object_info_p^.perform_move THEN
              set_volume_list_p^ [i].ms_class :=
                    set_volume_list_p^ [i].ms_class + move_object_info_p^.mass_storage_class;
            IFEND;
          IFEND;
        FOREND;

        IF NOT volume_found THEN
          osp$set_status_abnormal (rmc$resource_management_id, rme$vsn_not_part_of_set,
                current_value^.element_value^.name_value (1, 6), status);
          osp$append_status_parameter (osc$status_parameter_delimiter, move_object_info_p^.set_name,
                status);
          RETURN;
        IFEND;

        IF NOT volume_available THEN
          osp$set_status_abnormal (rmc$resource_management_id, pfe$movc_volume_unavailable,
                'DESTINATION_VOLUME', status);
          osp$append_status_parameter (osc$status_parameter_delimiter,
                current_value^.element_value^.name_value (1, 6), status);
          RETURN;
        IFEND;

        current_value := current_value^.link;
      WHILEND;
    IFEND;

    IF (move_object_info_p^.mass_storage_class * prohibited_classes) <> $dmt$class [] THEN
      osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$invalid_mass_storage_class, ' ', status);
      RETURN;
    IFEND;

    IF pvt [p$megabytes].specified THEN
      move_object_info_p^.move_bytes_threshold := pvt [p$megabytes].value^.integer_value.value * 1048576;
    ELSE
      move_object_info_p^.move_bytes_threshold := 0;
    IFEND;

    IF pvt [p$release_mass_storage].specified THEN
      IF pvt [p$release_mass_storage].value^.kind = clc$keyword THEN
        move_object_info_p^.release_mass_storage := pfc$when_insufficient_space;
      ELSE
        IF pvt [p$release_mass_storage].value^.boolean_value.value THEN
          move_object_info_p^.release_mass_storage := pfc$always;
        ELSE
          move_object_info_p^.release_mass_storage := pfc$never;
        IFEND;
      IFEND;
    ELSE
      move_object_info_p^.release_mass_storage := pfc$never;
    IFEND;

    IF pvt [p$volume_overflow_allowed].specified THEN
      move_object_info_p^.volume_overflow_allowed := pvt [p$volume_overflow_allowed].value^.boolean_value.
            value;
    ELSE
      move_object_info_p^.volume_overflow_allowed := TRUE;
    IFEND;

    IF pvt [p$wait].specified THEN
      move_object_info_p^.wait := pvt [p$wait].value^.boolean_value.value;
    ELSE
      move_object_info_p^.wait := TRUE;
    IFEND;

    IF pvt [p$source_volumes].specified AND (NOT pvt [p$destination_volumes].specified) THEN
      dest_volume_count := 0;
      FOR i := 1 TO number_of_volumes_in_set DO
        IF set_volume_list_p^ [i].available AND
              (set_volume_list_p^ [i].volume_type = pfc$unspecified_volume) AND
              ((move_object_info_p^.mass_storage_class * set_volume_list_p^ [i].ms_class)
              <> $dmt$class []) THEN
          dest_volume_count := dest_volume_count + 1;
        IFEND;
      FOREND;
      IF dest_volume_count > 0 THEN
        PUSH move_object_info_p^.dest_volume_list_p: [1 .. dest_volume_count];
        j := 1;
        FOR i := 1 TO number_of_volumes_in_set DO
          IF set_volume_list_p^ [i].available AND
                (set_volume_list_p^ [i].volume_type = pfc$unspecified_volume) AND
                ((move_object_info_p^.mass_storage_class * set_volume_list_p^ [i].ms_class)
                <> $dmt$class []) THEN
            set_volume_list_p^ [i].volume_type := pfc$destination_volume;
            move_object_info_p^.dest_volume_list_p^ [j] := ^set_volume_list_p^ [i];
            j := j + 1;
          IFEND;
        FOREND;
      ELSE
        osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_no_destination_volumes,
              move_object_info_p^.set_name, status);
        RETURN;
      IFEND;
    IFEND;

    IF pvt [p$destination_volumes].specified AND (NOT pvt [p$source_volumes].specified) THEN
      source_volume_count := 0;
      FOR i := 1 TO number_of_volumes_in_set DO
        IF set_volume_list_p^ [i].available AND
              (set_volume_list_p^ [i].volume_type = pfc$unspecified_volume) THEN
          source_volume_count := source_volume_count + 1;
        IFEND;
      FOREND;

      IF source_volume_count > 0 THEN
        PUSH move_object_info_p^.source_volume_list_p: [1 .. source_volume_count];
        j := 1;

        FOR i := 1 TO number_of_volumes_in_set DO
          IF set_volume_list_p^ [i].available AND
                (set_volume_list_p^ [i].volume_type = pfc$unspecified_volume) THEN
            set_volume_list_p^ [i].volume_type := pfc$source_volume;
            move_object_info_p^.source_volume_list_p^ [j] := ^set_volume_list_p^ [i];
            j := j + 1;
          IFEND;
        FOREND;
      IFEND;
    IFEND;

    traverse_hierarchy := NOT (pvt [p$files].specified OR pvt [p$catalogs].specified);
    traverse_set := traverse_hierarchy AND (pvt [p$hierarchy].value^.kind = clc$keyword);
    validate_mass_storage_class (move_object_info_p, traverse_set, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF (move_object_info_p^.source_volume_list_p = NIL) AND
          (NOT pvt [p$files].specified) AND (NOT pvt [p$catalogs].specified) THEN
      osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_no_source_volumes,
            move_object_info_p^.set_name, status);
      RETURN;
    IFEND;

    pfp$r3_get_move_obj_device_info (move_object_info_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    FOR i := 1 TO number_of_volumes_in_set DO
      set_volume_list_p^ [i].mass_storage_before := set_volume_list_p^ [i].mass_storage_available;
    FOREND;

    default_ring_attributes.r1 := #RING (^default_ring_attributes);
    default_ring_attributes.r2 := #RING (^default_ring_attributes);
    default_ring_attributes.r3 := #RING (^default_ring_attributes);
    clp$open_display_reference (pvt [p$output].value^.file_value^, NIL, fsc$list, default_ring_attributes,
          display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_opened := TRUE;
    #SPOIL (display_opened);

    osp$establish_block_exit_hndlr (^abort_handler);

  /display_file_open/
    BEGIN
      display_parameters (pvt[p$catalogs], pvt [p$files], pvt[p$source_volumes], pvt[p$destination_volumes],
            pvt[p$hierarchy], pvt[p$megabytes], move_object_info_p^, display_control, status);
      IF NOT status.normal THEN
        EXIT /display_file_open/;
      IFEND;

      IF pvt [p$catalogs].specified THEN
        current_value := pvt [p$catalogs].value;

        WHILE (current_value <> NIL) AND (current_value^.element_value <> NIL) DO
          fsp$evaluate_file_reference (current_value^.element_value^.file_value^,
                {NOT command_file_reference_allowed} FALSE, evaluated_file_reference, local_status);
          IF NOT local_status.normal THEN
            display_abnormal_status (local_status, display_control, ignore_status);
            EXIT /display_file_open/;
          IFEND;

          PUSH p_path: [1 .. evaluated_file_reference.number_of_path_elements];
          fsp$convert_fs_structure_to_pf (evaluated_file_reference, p_path);

          pfp$r3_physically_move_catalog (p_path^, move_object_info_p, local_status);

          move_object_info_p^.performance_statistics.catalog_count :=
                move_object_info_p^.performance_statistics.catalog_count + 1;

          IF (NOT move_object_info_p^.move_status.move_successful) AND
                (move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate) THEN
            osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_operator_termination, '',
                  local_status);
            display_catalog_move (p_path^, move_object_info_p^, display_control, local_status);
            EXIT /display_file_open/;
          ELSE
            display_catalog_move (p_path^, move_object_info_p^, display_control, local_status);
          IFEND;

          current_value := current_value^.link;
        WHILEND;
      IFEND;

      IF pvt [p$files].specified THEN
        current_value := pvt [p$files].value;

        WHILE (current_value <> NIL) AND (current_value^.element_value <> NIL) DO
          fsp$evaluate_file_reference (current_value^.element_value^.file_value^, FALSE
                {NOT command_file_reference_allowed} , evaluated_file_reference, local_status);
          IF NOT local_status.normal THEN
            display_abnormal_status (local_status, display_control, ignore_status);
            EXIT /display_file_open/;
          IFEND;

          PUSH p_path: [1 .. evaluated_file_reference.number_of_path_elements];
          fsp$convert_fs_structure_to_pf (evaluated_file_reference, p_path);
          clp$convert_cyc_ref_to_cyc_sel (evaluated_file_reference.cycle_reference, cl_cycle_selector);
          cycle_number := 1;

          pfp$r3_physically_move_cycle (p_path^, cl_cycle_selector.value, move_object_info_p, cycle_number,
                local_status);
          IF local_status.normal THEN
            p_cycle_number := ^cycle_number;
          ELSE
            IF evaluated_file_reference.cycle_reference.specification = fsc$cycle_number THEN
              cycle_number := evaluated_file_reference.cycle_reference.cycle_number;
              p_cycle_number := ^cycle_number;
            ELSE
              p_cycle_number := NIL;
            IFEND;
          IFEND;

          move_object_info_p^.performance_statistics.file_count :=
                move_object_info_p^.performance_statistics.file_count + 1;
          move_object_info_p^.performance_statistics.cycle_count :=
                move_object_info_p^.performance_statistics.cycle_count + 1;

          IF (NOT move_object_info_p^.move_status.move_successful) AND
                (move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate) THEN
            osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_operator_termination, '',
                  local_status);
            display_cycle_move (p_path^, move_object_info_p^, p_cycle_number, display_control, local_status);
            EXIT /display_file_open/;
          ELSE
            display_cycle_move (p_path^, move_object_info_p^, p_cycle_number, display_control, local_status);
          IFEND;

          current_value := current_value^.link;
        WHILEND;
      IFEND;

      IF traverse_hierarchy THEN
        IF pvt [p$hierarchy].value^.kind = clc$keyword THEN
          move_set (move_object_info_p, display_control, status);
        ELSE
          fsp$evaluate_file_reference (pvt [p$hierarchy].value^.file_value^, FALSE
                {NOT command_file_reference_allowed} , evaluated_file_reference, local_status);
          IF NOT local_status.normal THEN
            display_abnormal_status (local_status, display_control, ignore_status);
            EXIT /display_file_open/;
          IFEND;

          IF (fsp$path_element (^evaluated_file_reference, 1) ^ = fsc$local) THEN
            osp$set_status_abnormal ('CL', cle$not_permitted_on_loc_cat, '', status);
            EXIT /display_file_open/;
          IFEND;

          PUSH p_path: [1 .. evaluated_file_reference.number_of_path_elements];
          fsp$convert_fs_structure_to_pf (evaluated_file_reference, p_path);

          move_hierarchy (p_path^, move_object_info_p, display_control, ignore_status);
          IF (NOT move_object_info_p^.move_status.move_successful) AND
                ((move_object_info_p^.move_status.reason_for_move_failure = pfc$set_threshold_exceeded) OR
                (move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate)) THEN
            EXIT /display_file_open/;
          IFEND;
        IFEND;
      IFEND;

    END /display_file_open/;

    display_summary (move_object_info_p^, display_control, local_status);
    IF status.normal AND (NOT local_status.normal) THEN
      status := local_status;
    IFEND;

    clp$close_display (display_control, local_status);
    IF status.normal AND (NOT local_status.normal) THEN
      status := local_status;
    IFEND;

    display_opened := FALSE;
    #SPOIL (display_opened);

    osp$disestablish_cond_handler

  PROCEND pfp$move_classes_command;

?? OLDTITLE ??
?? NEWTITLE := 'convert_date_time', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to convert the information in a variable
{   of type OST$DATE_TIME to a displayable format.
{

  PROCEDURE convert_date_time
    (    date_time: ost$date_time;
     VAR str: ost$string);

    VAR
      date: ost$date,
      time: ost$time,
      status: ost$status;

    IF (date_time.year >= UPPERVALUE (date_time.year)) AND
          (date_time.month >= UPPERVALUE (date_time.month)) AND
          (date_time.day >= UPPERVALUE (date_time.day)) AND (date_time.hour >=
          UPPERVALUE (date_time.hour)) AND (date_time.minute >= UPPERVALUE (date_time.minute)) AND
          (date_time.second >= UPPERVALUE (date_time.second)) AND
          (date_time.millisecond >= UPPERVALUE (date_time.millisecond)) THEN
      str.size := 4;
      str.value := 'NONE';
      RETURN;
    IFEND;

    pmp$format_compact_date (date_time, osc$iso_date, date, status);
    IF status.normal THEN
      str.size := STRLENGTH (date.iso);
      str.value (1, str.size) := date.iso;
    ELSE
      str.size := 10;
      str.value (1, 10) := '????-??-??';
    IFEND;

    str.value (str.size + 1) := ' ';
    pmp$format_compact_time (date_time, osc$millisecond_time, time, status);
    IF status.normal THEN
      str.value (str.size + 2, STRLENGTH (time.millisecond)) := time.millisecond;
      str.size := str.size + 1 + STRLENGTH (time.millisecond);
    ELSE
      str.value (str.size + 2, 12) := '??:??:??.???';
      str.size := str.size + 1 + 12;
    IFEND;

  PROCEND convert_date_time;

?? OLDTITLE ??
?? NEWTITLE := 'display_abnormal_status', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display a status message to the
{   output file.
{

  PROCEDURE display_abnormal_status
    (    local_status: ost$status;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      message: ost$status_message,
      message_line_index: 1 .. osc$max_status_message_lines,
      p_message: ^ost$status_message,
      p_message_line: ^ost$status_message_line,
      p_message_line_count: ^ost$status_message_line_count,
      p_message_line_size: ^ost$status_message_line_size,
      str: ost$string;

    status.normal := TRUE;

    osp$format_message (local_status, osc$full_message_level, display_control.page_width, message, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    p_message := ^message;
    RESET p_message;
    NEXT p_message_line_count IN p_message;

    FOR message_line_index := 1 TO p_message_line_count^ DO
      NEXT p_message_line_size IN p_message;
      NEXT p_message_line: [p_message_line_size^] IN p_message;
      str.size := p_message_line_size^;
      str.value (1, str.size) := p_message_line^;

      clp$put_partial_display (display_control, str.value (1, str.size), clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND;

    clp$put_partial_display (display_control, ' ', clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_abnormal_status;

?? OLDTITLE ??
?? NEWTITLE := 'display_catalog_move', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display information associated with
{   a catalog move to the output file.  If the catalog cannot be moved, the
{   abnormal status is displayed to the output file.

  PROCEDURE display_catalog_move
    (    path: pft$path;
         move_object_info: pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: {i/o} ost$status);

    VAR
      class_str: string (1),
      fs_path: fst$path,
      fs_path_size: fst$path_size,
      index: integer,
      local_status: ost$status,
      str: ost$string,
      str_int: string (10);

    IF (NOT move_object_info.move_status.move_successful) AND
          (move_object_info.move_status.reason_for_move_failure = pfc$volume_threshold_exceeded) THEN
      RETURN;
    IFEND;

    pfp$convert_pft$path_to_fs_path (path, fs_path, fs_path_size);

    display_path (fs_path, fs_path_size, path_tab, display_control.page_width, display_control,
          local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;

    IF (NOT move_object_info.move_status.move_successful) AND (NOT status.normal) THEN
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, move_data_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Size: ', clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (move_object_info.move_status.allocated_size, {radix} 10,
          {include_radix} FALSE, ' ', str_int, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, class_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Mass Storage Class: ', clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    class_str (1) := move_object_info.move_status.ms_class;
    clp$put_partial_display (display_control, class_str (1, 1), clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, move_data_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, subfile_header, clc$no_trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, old_subfile_vsn_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, move_object_info.move_status.old_subfile_list_p^ [1].
          recorded_vsn, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, old_subfile_length_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (move_object_info.move_status.old_subfile_list_p^ [1].allocated_length,
          {radix} 10, {include_radix} FALSE, ' ', str_int, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, new_subfile_vsn_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, move_object_info.move_status.new_subfile_list_p^ [1].
          recorded_vsn, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, new_subfile_length_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (move_object_info.move_status.new_subfile_list_p^ [1].allocated_length,
          {radix} 10, {include_radix} FALSE, ' ', str_int, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, ' ', clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_catalog_move;

?? OLDTITLE ??
?? NEWTITLE := 'display_class_summary', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display movement statistics for each
{   affected mass storage class.
{

  PROCEDURE display_class_summary
    (    move_object_info: pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      class: char,
      class_str: string (1);

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, 'Class Summary', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  /display_class/
    FOR class := 'A' TO 'Z' DO
      IF (move_object_info.class_statistics [class].objects_moved = 0) AND
            (move_object_info.class_statistics [class].objects_not_moved = 0) THEN
        CYCLE /display_class/;
      IFEND;

      clp$horizontal_tab_display (display_control, title_tab, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, 'Mass Storage Class: ', clc$no_trim, amc$continue, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      class_str (1) := class;
      clp$put_partial_display (display_control, class_str (1, 1), clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      display_movement_statistics (move_object_info.class_statistics [class], display_control, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND /display_class/;

  PROCEND display_class_summary;

?? OLDTITLE ??
?? NEWTITLE := 'display_cycle_move', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display information associated with
{   the move of a file cycle to the output file.  If the file cycle could
{   not be moved, the abnormal status is displayed to the output file.
{

  PROCEDURE display_cycle_move
    (    path: pft$path;
         move_object_info: pft$move_object_info;
         p_cycle_number: ^fst$cycle_number;
     VAR display_control: clt$display_control;
     VAR status: {i/o} ost$status);

    VAR
      action: string (30),
      class_str: string (1),
      fs_path: fst$path,
      fs_path_size: fst$path_size,
      i: integer,
      local_status: ost$status,
      max_number_of_subfiles: integer,
      recorded_vsn: rmt$recorded_vsn,
      str: ost$string,
      str_int: string (10),
      subfile_length: amt$file_byte_address;

    IF (NOT move_object_info.move_status.move_successful) AND
          (move_object_info.move_status.reason_for_move_failure = pfc$volume_threshold_exceeded) THEN
      RETURN;
    IFEND;

    pfp$convert_pft$path_to_fs_path (path, fs_path, fs_path_size);

    IF (p_cycle_number <> NIL) AND (fs_path_size < fsc$max_path_size - 4) THEN
      STRINGREP (fs_path (fs_path_size + 1, * ), i, p_cycle_number^);
      fs_path (fs_path_size + 1, 1) := '.';
      fs_path_size := fs_path_size + i;
    IFEND;

    display_path (fs_path, fs_path_size, path_tab, display_control.page_width, display_control, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;

    IF (NOT move_object_info.move_status.move_successful) AND (NOT status.normal) THEN
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, move_data_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Size: ', clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (move_object_info.move_status.allocated_size, {radix} 10,
          {include_radix} FALSE, ' ', str_int, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, class_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Mass Storage Class: ', clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    class_str (1) := move_object_info.move_status.ms_class;
    clp$put_partial_display (display_control, class_str (1, 1), clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, data_residence_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Data Residence: ', clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    CASE move_object_info.move_status.data_residence OF
    = pfc$unreleasable_data =
      action := ' MASS STORAGE          ';
    = pfc$releasable_data =
      action := ' DUPLICATED            ';
    = pfc$offline_data =
      action := ' OFFLINE               ';
    = pfc$release_data_requested =
      action := ' OFFLINE               ';
    ELSE
      action := ' UNKNOWN               ';
    CASEND;

    clp$put_partial_display (display_control, action, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, move_data_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Modification Date Time: ', clc$no_trim, amc$continue,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    convert_date_time (move_object_info.move_status.modification_date_time, str);

    clp$put_partial_display (display_control, str.value (1, str.size), clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, move_data_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, subfile_header, clc$no_trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF move_object_info.move_status.new_subfile_list_p = NIL THEN
      max_number_of_subfiles := UPPERBOUND (move_object_info.move_status.old_subfile_list_p^);
    ELSEIF UPPERBOUND (move_object_info.move_status.old_subfile_list_p^) >=
          UPPERBOUND (move_object_info.move_status.new_subfile_list_p^) THEN
      max_number_of_subfiles := UPPERBOUND (move_object_info.move_status.old_subfile_list_p^);
    ELSE
      max_number_of_subfiles := UPPERBOUND (move_object_info.move_status.new_subfile_list_p^);
    IFEND;

    FOR i := 1 TO max_number_of_subfiles DO
      IF i <= UPPERBOUND (move_object_info.move_status.old_subfile_list_p^) THEN
        recorded_vsn := move_object_info.move_status.old_subfile_list_p^ [i].recorded_vsn;
        subfile_length := move_object_info.move_status.old_subfile_list_p^ [i].allocated_length;
      ELSE
        recorded_vsn := rmc$unspecified_vsn;
        subfile_length := 0;
      IFEND;

      clp$horizontal_tab_display (display_control, old_subfile_vsn_tab, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, recorded_vsn, clc$trim, amc$continue, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$horizontal_tab_display (display_control, old_subfile_length_tab, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF recorded_vsn <> rmc$unspecified_vsn THEN
        clp$convert_integer_to_rjstring (subfile_length, {radix} 10, {include_radix} FALSE, ' ', str_int,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        clp$put_partial_display (display_control, str_int, clc$trim, amc$continue, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

      IF move_object_info.move_status.new_subfile_list_p <> NIL THEN
        IF i <= UPPERBOUND (move_object_info.move_status.new_subfile_list_p^) THEN
          recorded_vsn := move_object_info.move_status.new_subfile_list_p^ [i].recorded_vsn;
          subfile_length := move_object_info.move_status.new_subfile_list_p^ [i].allocated_length;
        ELSE
          recorded_vsn := rmc$unspecified_vsn;
          subfile_length := 0;
        IFEND;

        clp$horizontal_tab_display (display_control, new_subfile_vsn_tab, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        clp$put_partial_display (display_control, recorded_vsn, clc$trim, amc$continue, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        clp$horizontal_tab_display (display_control, new_subfile_length_tab, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        IF recorded_vsn <> rmc$unspecified_vsn THEN
          clp$convert_integer_to_rjstring (subfile_length, {radix} 10, {include_radix} FALSE, ' ', str_int,
                status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
        ELSE
          str_int := ' ';
        IFEND;

        clp$put_partial_display (display_control, str_int, clc$trim, amc$continue, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      ELSEIF i = 1 THEN
        clp$horizontal_tab_display (display_control, new_subfile_vsn_tab, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;

        clp$put_partial_display (display_control, '  Cycle Released', clc$trim, amc$continue, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      IFEND;

      clp$put_partial_display (display_control, ' ', clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND;

    clp$put_partial_display (display_control, ' ', clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
  PROCEND display_cycle_move;

?? OLDTITLE ??
?? NEWTITLE := 'display_movement_statistics', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display movement statistics to the
{   output file.
{

  PROCEDURE display_movement_statistics
    (    movement_statistics: pft$movement_statistics;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      str: string (12);

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Bytes Moved:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.bytes_moved, {radix} 10, {include_radix} FALSE, ' ',
          str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Objects Moved:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.objects_moved, {radix} 10, {include_radix} FALSE,
          ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Objects Not Moved:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.objects_not_moved, {radix} 10, {include_radix} FALSE,
          ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, subheader_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Abnormal Status:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.abnormal_status, {radix} 10, {include_radix} FALSE,
          ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, subheader_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Cycle Busy:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.cycle_busy, {radix} 10, {include_radix} FALSE, ' ',
          str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, subheader_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Insufficient Space:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.insufficient_space, {radix} 10,
          {include_radix} FALSE, ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, subheader_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'No Available Space:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.no_available_space, {radix} 10,
          {include_radix} FALSE, ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, subheader_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Unrecovered Read Error:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.unrecovered_read_error, {radix} 10,
          {include_radix} FALSE, ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Bytes Released:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.bytes_released, {radix} 10, {include_radix} FALSE,
          ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Cycles Released:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (movement_statistics.cycles_released, {radix} 10, {include_radix} FALSE,
          ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_movement_statistics;

?? OLDTITLE ??
?? NEWTITLE := 'display_overall_summary', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display information about the type and
{   number of objects scanned to the output file.
{

  PROCEDURE display_overall_summary
    (    move_object_info: pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, 'Overall Summary', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_movement_statistics (move_object_info.overall_statistics, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_overall_summary;

?? OLDTITLE ??
?? NEWTITLE := 'display_parameters', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display the values specified for the
{   command parameters to the output file.
{

  PROCEDURE display_parameters
    (    catalog_parameter: clt$parameter_value;
         file_parameter: clt$parameter_value;
         source_vol_parameter: clt$parameter_value;
         dest_vol_parameter: clt$parameter_value;
         hierarchy_parameter: clt$parameter_value;
         megabytes_parameter: clt$parameter_value;
         move_object_info: pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    CONST
      catalogs_header = 'CATALOGS',
      files_header = 'FILES',
      source_volumes_header = 'SOURCE_VOLUMES',
      destination_volumes_header = 'DESTINATION_VOLUMES',
      hierarchy_header = 'HIERARCHY',
      parameter_header = 'MOVE_CLASSES Parameters ',
      mass_storage_class_header = 'MASS_STORAGE_CLASSES',
      megabytes_header = 'MEGABYTES',
      perform_move_header = 'PERFORM_MOVE',
      release_mass_storage_header = 'RELEASE_MASS_STORAGE',
      volume_overflow_allowed_header = 'VOLUME_OVERFLOW_ALLOWED',
      wait_header = 'WAIT',
      first_tab_column = 2,
      header_tab_column = 4,
      value_tab_column = 35;

    VAR
      ch: 'A' .. 'Z',
      current_value_p: ^clt$data_value,
      ec_str: ost$string,
      element_count: integer,
      evaluated_file_reference: fst$evaluated_file_reference,
      fs_path_size: fst$path_size,
      mb_str: ost$string,
      p_fs_path: ^fst$path,
      pos: 0 .. 255,
      str: string (255);

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    {
    { Display parameter header.
    {
    clp$horizontal_tab_display (display_control, first_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, parameter_header, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display CATALOGS parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, catalogs_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF catalog_parameter.specified THEN
      clp$convert_integer_to_string (clp$count_list_elements (catalog_parameter.value), {radix} 10,
            {include_radix} FALSE, ec_str, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      str (1, 8) := 'List of ';
      str (9, ec_str.size) := ec_str.value (1, ec_str.size);
      str (ec_str.size + 9, 19) := ' Catalogs Specified';
      clp$put_partial_display (display_control, str (1, ec_str.size + 27), clc$trim, amc$terminate, status);
    ELSE
      clp$put_partial_display (display_control, 'UNSPECIFIED', clc$trim, amc$terminate, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display FILES parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, files_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF file_parameter.specified THEN
      clp$convert_integer_to_string (clp$count_list_elements (file_parameter.value), {radix} 10,
            {include_radix} FALSE, ec_str, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      str (1, 8) := 'List of ';
      str (9, ec_str.size) := ec_str.value (1, ec_str.size);
      str (ec_str.size + 9, 16) := ' Files Specified';
      clp$put_partial_display (display_control, str (1, ec_str.size + 24), clc$trim, amc$terminate, status);
    ELSE
      clp$put_partial_display (display_control, 'UNSPECIFIED', clc$trim, amc$terminate, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display SOURCE_VOLUMES parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, source_volumes_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_volume_list_parameter (source_vol_parameter, value_tab_column, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display DESTINATION_VOLUMES parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, destination_volumes_header, clc$no_trim, amc$continue,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_volume_list_parameter (dest_vol_parameter, value_tab_column, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display HIERARCHY parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, hierarchy_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF hierarchy_parameter.specified THEN
      IF hierarchy_parameter.value^.kind = clc$keyword THEN
        clp$put_partial_display (display_control, 'SET', clc$trim, amc$terminate, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
      ELSE
        fsp$evaluate_file_reference (hierarchy_parameter.value^.file_value^, FALSE
              {NOT command_file_reference_allowed} , evaluated_file_reference, status);
        IF NOT status.normal THEN
          RETURN
        IFEND;
        PUSH p_fs_path;

        clp$convert_file_ref_to_string (evaluated_file_reference, FALSE, p_fs_path^, fs_path_size, status);
        IF NOT status.normal THEN
          RETURN
        IFEND;

        display_path (p_fs_path^, fs_path_size, value_tab_column, display_control.page_width,
              display_control, status);
      IFEND;
    ELSE
      clp$put_partial_display (display_control, 'UNSPECIFIED', clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;
    {
    { Display MASS_STORAGE_CLASSES parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, mass_storage_class_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF move_object_info.mass_storage_class <> $dmt$class [] THEN
      str := '[';
      pos := 2;
      FOR ch := 'A' TO 'Z' DO
        IF ch IN move_object_info.mass_storage_class THEN
          str (pos) := ch;
          str (pos + 1) := ',';
          pos := pos + 2;
        IFEND;
      FOREND;
      pos := pos - 1;
      str (pos) := ']';
    IFEND;

    clp$put_partial_display (display_control, str (1, pos), clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display MEGABYTES parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, megabytes_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF move_object_info.move_bytes_threshold > 0 THEN

      clp$convert_integer_to_string (megabytes_parameter.value^.integer_value.value, {radix} 10,
            {include_radix} FALSE, mb_str, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, mb_str.value (1, mb_str.size), clc$no_trim, amc$continue,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, ' (', clc$no_trim, amc$continue, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$convert_integer_to_string (move_object_info.move_bytes_threshold, {radix} 10,
            {include_radix} FALSE, mb_str, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, mb_str.value (1, mb_str.size), clc$no_trim, amc$continue,
            status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, ' BYTES)', clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    ELSE
      clp$put_partial_display (display_control, 'UNSPECIFIED', clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;
    {
    { Display PERFORM_MOVE parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, perform_move_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF move_object_info.perform_move THEN
      clp$put_partial_display (display_control, 'TRUE', clc$trim, amc$terminate, status);
    ELSE
      clp$put_partial_display (display_control, 'FALSE', clc$trim, amc$terminate, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display RELEASE_MASS_STORAGE parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, release_mass_storage_header, clc$no_trim, amc$continue,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    CASE move_object_info.release_mass_storage OF
    = pfc$always =
      clp$put_partial_display (display_control, 'TRUE', clc$trim, amc$terminate, status);
    = pfc$never =
      clp$put_partial_display (display_control, 'FALSE', clc$trim, amc$terminate, status);
    = pfc$when_insufficient_space =
      clp$put_partial_display (display_control, 'WHEN_SPACE_UNAVAILABLE', clc$trim, amc$terminate, status);
    CASEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display VOLUME_OVERFLOW_ALLOWED parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, volume_overflow_allowed_header, clc$no_trim, amc$continue,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF move_object_info.volume_overflow_allowed THEN
      clp$put_partial_display (display_control, 'TRUE', clc$trim, amc$terminate, status);
    ELSE
      clp$put_partial_display (display_control, 'FALSE', clc$trim, amc$terminate, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    {
    { Display WAIT parameter.
    {
    clp$horizontal_tab_display (display_control, header_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, wait_header, clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, value_tab_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF move_object_info.wait THEN
      clp$put_partial_display (display_control, 'TRUE', clc$trim, amc$terminate, status);
    ELSE
      clp$put_partial_display (display_control, 'FALSE', clc$trim, amc$terminate, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_parameters;

?? OLDTITLE ??
?? NEWTITLE := 'display_path', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display a path to the output file.
{

  PROCEDURE display_path
    (VAR fs_path: fst$path;
         fs_path_size: fst$path_size;
         left_column: amt$page_width;
         right_column: amt$page_width;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      chunk_count: 0 .. fsc$max_path_elements,
      display_chunks: clt$path_display_chunks,
      i: 0 .. fsc$max_path_elements,
      terminate_string: string (2);

    clp$build_path_subtitle (fs_path, fs_path_size, right_column - left_column, chunk_count, display_chunks);

    terminate_string := '..';
    FOR i := 1 TO chunk_count DO
      clp$horizontal_tab_display (display_control, left_column, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_partial_display (display_control, fs_path (display_chunks [i].position,
            display_chunks [i].length), clc$trim, amc$continue, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      IF i = chunk_count THEN
        terminate_string := '  ';
      IFEND;

      clp$put_partial_display (display_control, terminate_string, clc$trim, amc$terminate, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    FOREND;

  PROCEND display_path;

?? OLDTITLE ??
?? NEWTITLE := 'display_performance_statistics', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to calculate performance statistics and
{   display them to the output file.
{

  PROCEDURE display_performance_statistics
    (    performance_statistics: pft$performance_statistics;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    CONST
      cp_time_column = integer_value_tab - 5,
      date_time_column = integer_value_tab - 13,
      seconds_str = '(seconds)',
      seconds_tab = integer_value_tab + 11;

    VAR
      elapsed_cp_time: real,
      elapsed_time: integer,
      final_date_time: ost$date_time,
      final_microsecond_clock: integer,
      final_task_cp_time: pmt$task_cp_time,
      os_str: ost$string,
      str_int: string (10),
      str_len: integer,
      str_real: string (15);

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, 'Performance Statistics', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Catalog Count: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (performance_statistics.catalog_count, {radix} 10, {include_radix} FALSE,
          ' ', str_int, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'File Count: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (performance_statistics.file_count, {radix} 10, {include_radix} FALSE,
          ' ', str_int, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Cycle Count: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (performance_statistics.cycle_count, {radix} 10, {include_radix} FALSE,
          ' ', str_int, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

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

    pmp$get_microsecond_clock (final_microsecond_clock, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    pmp$get_task_cp_time (final_task_cp_time, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Initial Date Time: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, date_time_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    convert_date_time (performance_statistics.initial_date_time, os_str);

    clp$put_partial_display (display_control, os_str.value (1, os_str.size), clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Final Date Time: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, date_time_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    convert_date_time (final_date_time, os_str);

    clp$put_partial_display (display_control, os_str.value (1, os_str.size), clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    elapsed_time := (final_microsecond_clock -
          performance_statistics.initial_microsecond_clock) DIV 1000000;
    STRINGREP (str_int, str_len, elapsed_time:10);

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Elapsed Time: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_int, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, seconds_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, seconds_str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    elapsed_cp_time := $real(final_task_cp_time.monitor_time -
          performance_statistics.initial_task_cp_time.monitor_time) / 1000000.0;
    STRINGREP (str_real, str_len, elapsed_cp_time: 15: 6);

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Monitor CP Time: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, cp_time_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_real, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, seconds_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, seconds_str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    elapsed_cp_time := $real(final_task_cp_time.task_time -
          performance_statistics.initial_task_cp_time.task_time) / 1000000.0;
    STRINGREP (str_real, str_len, elapsed_cp_time: 15: 6);

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Job CP Time: ', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, cp_time_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str_real, clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, seconds_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, seconds_str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_performance_statistics;

?? OLDTITLE ??
?? NEWTITLE := 'display_summary', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display summary information to the
{   output file after the move is completed.
{

  PROCEDURE display_summary
    (    move_object_info: pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      str: string (12);

    display_overall_summary (move_object_info, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_class_summary (move_object_info, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_volume_summary (move_object_info, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    display_performance_statistics (move_object_info.performance_statistics, display_control, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_summary;


?? OLDTITLE ??
?? NEWTITLE := 'display_volume', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display movement statistics for each
{   affected volume to the output file.
{

  PROCEDURE display_volume
    (    move_object_info: pft$move_object_info;
         volume_index: integer;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      str: string (12),
      volume: pft$mo_volume;

    volume := move_object_info.set_volume_list_p^ [volume_index];

    IF NOT volume.available THEN
      clp$put_display (display_control, ' ', clc$trim, status);
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, title_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Volume: ', clc$no_trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, volume.recorded_vsn, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Bytes Moved To:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.bytes_moved_to, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Catalogs Moved To:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.catalogs_moved_to, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Cycles Moved To:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.cycles_moved_to, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Bytes Moved From:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.bytes_moved_from, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Catalogs Moved From:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.catalogs_moved_from, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Cycles Moved From:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.cycles_moved_from, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Bytes Released:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.bytes_released, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Cycles Released:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.cycles_released, {radix} 10, {include_radix} FALSE, ' ', str,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Mass Storage Available Before:', clc$trim, amc$continue,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.mass_storage_before, {radix} 10, {include_radix} FALSE, ' ',
          str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Mass Storage Available After:', clc$trim, amc$continue,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.mass_storage_available, {radix} 10, {include_radix} FALSE, ' ',
          str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, header_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, 'Mass Storage Capacity:', clc$trim, amc$continue, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$horizontal_tab_display (display_control, integer_value_tab, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$convert_integer_to_rjstring (volume.mass_storage_capacity, {radix} 10, {include_radix} FALSE,
          ' ', str, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_partial_display (display_control, str, clc$trim, amc$terminate, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

  PROCEND display_volume;

?? OLDTITLE ??
?? NEWTITLE := 'display_volume_list_parameter', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to display the list of volumes specified
{   by the source and destination volume list parameters to the output file.
{

  PROCEDURE display_volume_list_parameter
    (    volume_list_parameter: clt$parameter_value;
         left_column: amt$page_width;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      current_value_p: ^clt$data_value,
      max_str_length: 0 .. 255,
      pos: 0 .. 255,
      str: string (255);


    clp$horizontal_tab_display (display_control, left_column, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF volume_list_parameter.specified THEN
      max_str_length := display_control.page_width - left_column;
      str := '(';
      pos := 2;
      current_value_p := volume_list_parameter.value;
      WHILE (current_value_p <> NIL) AND (current_value_p^.element_value <> NIL) DO
        IF (pos + 7) < max_str_length THEN
          str (pos, 6) := current_value_p^.element_value^.name_value (1, 6);
          str (pos + 6, 1) := ' ';
          pos := pos + 7;
        ELSE
          str (pos, 2) := '..';
          pos := pos + 1;
          clp$put_partial_display (display_control, str (1, pos), clc$trim, amc$terminate, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;
          clp$horizontal_tab_display (display_control, left_column, status);
          IF NOT status.normal THEN
            RETURN;
          IFEND;

          str (1, 6) := current_value_p^.element_value^.name_value (1, 6);
          str (7) := ' ';
          pos := 8;
        IFEND;
        current_value_p := current_value_p^.link;
      WHILEND;

      pos := pos - 1;
      str (pos, 1) := ')';
      clp$put_partial_display (display_control, str (1, pos), clc$trim, amc$terminate, status);
    ELSE
      clp$put_partial_display (display_control, 'UNSPECIFIED', clc$trim, amc$terminate, status);
    IFEND;

  PROCEND display_volume_list_parameter;

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

  PROCEDURE display_volume_summary
    (    move_object_info: pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      class: char,
      class_str: string (1),
      unspecified_volume_count: ost$non_negative_integers,
      volume_index: ost$positive_integers;

    IF move_object_info.perform_move THEN
      dmp$utility_flush_logs_r3;
      pfp$r3_get_move_obj_device_info (^move_object_info, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, 'Source Volumes', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    unspecified_volume_count := 0;

    FOR volume_index := 1 TO UPPERBOUND (move_object_info.set_volume_list_p^) DO
      IF move_object_info.set_volume_list_p^ [volume_index].volume_type = pfc$source_volume THEN
        display_volume (move_object_info, volume_index, display_control, status);
      ELSEIF move_object_info.set_volume_list_p^ [volume_index].volume_type = pfc$unspecified_volume THEN
        unspecified_volume_count := unspecified_volume_count + 1;
      IFEND;
    FOREND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, 'Destination Volumes', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    FOR volume_index := 1 TO UPPERBOUND (move_object_info.set_volume_list_p^) DO
      IF move_object_info.set_volume_list_p^ [volume_index].volume_type = pfc$destination_volume THEN
        display_volume (move_object_info, volume_index, display_control, status);
      IFEND;
    FOREND;

    clp$put_display (display_control, ' ', clc$trim, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF unspecified_volume_count > 0 THEN
      clp$put_display (display_control, 'Other Volumes', clc$trim, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_display (display_control, ' ', clc$trim, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      FOR volume_index := 1 TO UPPERBOUND (move_object_info.set_volume_list_p^) DO
        IF move_object_info.set_volume_list_p^ [volume_index].volume_type = pfc$unspecified_volume THEN
          display_volume (move_object_info, volume_index, display_control, status);
        IFEND;
      FOREND;
    IFEND;

  PROCEND display_volume_summary;

?? OLDTITLE ??
?? NEWTITLE := 'initialize_set_volume_list', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to initialize information in the
{   SET_VOLUME_LIST which is contained in the MOVE_OBJECT_INFO structure.
{

  PROCEDURE initialize_set_volume_list
    (    set_volume_list_p: ^pft$mo_volume_list;
     VAR status: ost$status);

    VAR
      element_status: iot$unit_status,
      found: boolean,
      i: integer,
      j: integer,
      ms_volume_count: integer,
      ms_volumes_p: ^array [1 .. * ] of cmt$mass_storage_volume,
      state: cmt$element_state;

    status.normal := TRUE;

    IF set_volume_list_p = NIL THEN
      RETURN;
    IFEND;

    { Obtain the class membership of each volume in the configuration which is ON and ENABLED.

    cmp$get_ms_volumes (ms_volume_count);
    PUSH ms_volumes_p: [1 .. ms_volume_count];
    cmp$get_ms_volume_info (ms_volumes_p^);

  /process_volume/
    FOR i := 1 TO UPPERBOUND (set_volume_list_p^) DO
      found := FALSE;

      set_volume_list_p^ [i].available := FALSE;
      set_volume_list_p^ [i].bytes_moved_from := 0;
      set_volume_list_p^ [i].bytes_moved_to := 0;
      set_volume_list_p^ [i].bytes_released := 0;
      set_volume_list_p^ [i].catalogs_moved_from := 0;
      set_volume_list_p^ [i].catalogs_moved_to := 0;
      set_volume_list_p^ [i].cycles_moved_from := 0;
      set_volume_list_p^ [i].cycles_moved_to := 0;
      set_volume_list_p^ [i].cycles_released := 0;
      set_volume_list_p^ [i].logical_unit_number := 0;
      set_volume_list_p^ [i].mass_storage_available := 0;
      set_volume_list_p^ [i].mass_storage_before := 0;
      set_volume_list_p^ [i].mass_storage_capacity := 0;
      set_volume_list_p^ [i].move_bytes_threshold_exceeded := FALSE;
      set_volume_list_p^ [i].ms_class := $dmt$class [ ];
      set_volume_list_p^ [i].volume_type := pfc$unspecified_volume;

    /locate_volume/
      FOR j := 1 TO ms_volume_count DO
        IF set_volume_list_p^ [i].recorded_vsn = ms_volumes_p^ [j].recorded_vsn THEN
          found := TRUE;
          EXIT /locate_volume/;
        IFEND;
      FOREND /locate_volume/;

      IF NOT found THEN
        CYCLE /process_volume/;
      IFEND;

      cmp$get_element_state_via_lun (ms_volumes_p^ [j].lun, state);
      IF state <> cmc$on THEN
        CYCLE /process_volume/;
      IFEND;

      cmp$get_ms_status_via_lun (ms_volumes_p^ [j].lun, element_status);
      IF element_status.disabled THEN
        CYCLE /process_volume/;
      IFEND;

      set_volume_list_p^ [i].available := TRUE;
      set_volume_list_p^ [i].logical_unit_number := ms_volumes_p^ [j].lun;
      set_volume_list_p^ [i].ms_class := ms_volumes_p^ [j].class;

    FOREND /process_volume/;

  PROCEND initialize_set_volume_list;

?? OLDTITLE ??
?? NEWTITLE := 'move_catalog', EJECT ??
{ PURPOSE
{   This procedure attempts to move a specified catalog and it's contents.
{   PFP$R3_GET_OBJECT_INFORMATION is called to obtain a list of all objects
{   in the catalog.  If the catalog itself is to be moved,
{   PFP$R3_PHYSICALLY_MOVE_CATALOG is called to move it.  MOVE_FILE is then
{   called to move all cycles of each file contained in the catalog that are to be
{   be moved.  After moving all cycles in the catalog, MOVE_CATALOG calls
{   itself recursively to move each subcatalog contained in the catalog.

  PROCEDURE move_catalog
    (    path: pft$path;
         object_info_p: ^SEQ ( * );
         move_object_info_p: ^pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      catalog_object_entry_p: ^fst$goi_object,
      catalog_object_info_p: ^fst$goi_object_information,
      catalog_reference: fst$path,
      current_catalog_index: pft$catalog_path_index,
      current_object_info_p: ^SEQ ( * ),
      evaluated_file_reference: fst$evaluated_file_reference,
      fs_path_size: fst$path_size,
      ignore_status: ost$status,
      length: integer,
      line: string (255),
      local_status: ost$status,
      move_object: boolean,
      object_index: integer,
      object_list_p: ^fst$goi_object_list,
      object_path: ^pft$path,
      p_fs_path: ^fst$path,
      path_index: pft$catalog_path_index,
      unused_sequence_p: ^SEQ ( * );

    current_catalog_index := UPPERBOUND (path);
    PUSH object_path: [1 .. current_catalog_index + 1];
    FOR path_index := 1 TO current_catalog_index DO
      object_path^ [path_index] := path [path_index];
    FOREND;

    fsp$build_file_ref_from_elems (^path, catalog_reference, status);
    IF NOT status.normal THEN
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

    current_object_info_p := object_info_p;

    clp$evaluate_file_reference (catalog_reference,
          $clt$file_ref_parsing_options [clc$command_file_ref_allowed], {resolve_cycle_number} FALSE,
          evaluated_file_reference, status);
    IF NOT status.normal THEN
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

    pfp$r3_get_object_information (evaluated_file_reference, catalog_information_request,
          {validation_criteria} NIL, current_object_info_p, status);
    IF NOT status.normal THEN
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

    {
    { Create an adaptable sequence pointer that defines the unused portion of the sequence.
    { PFP$R3_GET_OBJECT_INFORMATION leaves the sequence pointer at the next available byte in the sequence.
    {
    NEXT unused_sequence_p: [[REP #SIZE (current_object_info_p^) -
          i#current_sequence_position (current_object_info_p) OF cell]] IN current_object_info_p;
    RESET unused_sequence_p;

    {
    { Retrieve the object and object_list for the current catalog.
    {
    RESET current_object_info_p;
    NEXT catalog_object_info_p IN current_object_info_p;

    { Verify whether the catalog_object_info_p pointer or the object pointer
    { inside is NIL and if so return with an error message.

    IF catalog_object_info_p = NIL THEN
      PUSH p_fs_path;
      clp$convert_file_ref_to_string (evaluated_file_reference, FALSE, p_fs_path^, fs_path_size,
            local_status);
      IF local_status.normal THEN
        STRINGREP (line, length, 'MOVE_CATALOG - NIL pointer returned for catalog ',
              p_fs_path^ (1, fs_path_size), '- possibly an empty and/or attached master catalog');
        pmp$log_ascii (line (1, length), $pmt$ascii_logset [pmc$job_log], pmc$msg_origin_system,
              ignore_status);
        osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$pf_system_error,
              'NIL Pointer returned by MOVE_CATALOG.  See job log for details.', status);
      IFEND;
      RETURN;
    IFEND;

    IF catalog_object_info_p^.object = NIL THEN
      PUSH p_fs_path;
      clp$convert_file_ref_to_string (evaluated_file_reference, FALSE, p_fs_path^, fs_path_size,
            local_status);
      IF local_status.normal THEN
        STRINGREP (line, length, 'MOVE_CATALOG - NIL pointer returned for object in the catalog ',
              p_fs_path^ (1, fs_path_size), '- possibly an empty and/or attached master catalog');
        pmp$log_ascii (line (1, length), $pmt$ascii_logset [pmc$job_log], pmc$msg_origin_system,
              ignore_status);
        osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$pf_system_error,
              'NIL Pointer returned by MOVE_CATALOG.  See job log for details.', status);
      IFEND;
      RETURN;
    IFEND;

    IF catalog_object_info_p^.object^.object_type <> fsc$goi_catalog_object THEN
      osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$nth_name_not_subcatalog,
            catalog_object_info_p^.resolved_path^, status);
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

    catalog_object_entry_p := catalog_object_info_p^.object;
    object_list_p := catalog_object_entry_p^.subcatalog_and_file_object_list;
    move_object_info_p^.performance_statistics.catalog_count :=
           move_object_info_p^.performance_statistics.catalog_count + 1;

    validate_object_move (catalog_object_entry_p, move_object_info_p, move_object);

    IF move_object THEN
      pfp$r3_physically_move_catalog (path, move_object_info_p, local_status);
      IF move_object_info_p^.move_status.move_successful THEN
        display_catalog_move (path, move_object_info_p^, display_control, local_status);
      ELSE
        IF move_object_info_p^.move_status.reason_for_move_failure = pfc$set_threshold_exceeded THEN
          RETURN;
        ELSEIF move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate THEN
          osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_operator_termination, '',
                local_status);
          display_catalog_move (path, move_object_info_p^, display_control, local_status);
          RETURN;
        ELSEIF move_object_info_p^.move_bytes_threshold > 0 THEN
          IF (move_object_info_p^.move_status.reason_for_move_failure = pfc$no_available_space) AND
                pfp$no_space_movc_dest_volumes (move_object_info_p) THEN
            RETURN;
          IFEND;
        ELSE
          display_catalog_move (path, move_object_info_p^, display_control, local_status);
        IFEND;
      IFEND;
    IFEND;

    IF object_list_p = NIL THEN
      RETURN;
    IFEND;

    {
    { Process all files in the current catalog.
    {
    FOR object_index := LOWERBOUND (object_list_p^) TO UPPERBOUND (object_list_p^) DO
      IF object_list_p^ [object_index].object_type = fsc$goi_file_object THEN
        object_path^ [current_catalog_index + 1] := object_list_p^ [object_index].file_name;

        move_file (object_path^, ^object_list_p^ [object_index], move_object_info_p, display_control);
        IF (NOT move_object_info_p^.move_status.move_successful) AND
              ((move_object_info_p^.move_status.reason_for_move_failure = pfc$set_threshold_exceeded) OR
              (move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate) OR
              ((move_object_info_p^.move_bytes_threshold > 0) AND
              (move_object_info_p^.move_status.reason_for_move_failure = pfc$no_available_space) AND
              pfp$no_space_movc_dest_volumes (move_object_info_p))) THEN
          RETURN;
        IFEND;
      IFEND;
    FOREND;

    {
    { Process all catalogs in the current catalog.
    { A recursive call to MOVE_CATALOG is used to traverse the entire catalog structure.
    {
    FOR object_index := LOWERBOUND (object_list_p^) TO UPPERBOUND (object_list_p^) DO
      IF object_list_p^ [object_index].object_type = fsc$goi_catalog_object THEN
        object_path^ [current_catalog_index + 1] := object_list_p^ [object_index].catalog_name;
        move_catalog (object_path^, unused_sequence_p, move_object_info_p, display_control, ignore_status);
        IF (NOT move_object_info_p^.move_status.move_successful) AND
              ((move_object_info_p^.move_status.reason_for_move_failure = pfc$set_threshold_exceeded) OR
              (move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate) OR
              ((move_object_info_p^.move_bytes_threshold > 0) AND
              (move_object_info_p^.move_status.reason_for_move_failure = pfc$no_available_space) AND
              pfp$no_space_movc_dest_volumes (move_object_info_p))) THEN
          RETURN;
        IFEND;
      IFEND;
    FOREND;

  PROCEND move_catalog;

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

{ PURPOSE
{   This procedure examines each cycle of the specified file to select the
{   cycles that are candidates to be moved.  PFP$R3_PHYSICALLY_MOVE_CYCLE is
{   then called to move the selected cycles.

  PROCEDURE move_file
    (    path: pft$path;
         file_object_p: ^fst$goi_object;
         move_object_info_p: ^pft$move_object_info;
     VAR display_control: clt$display_control);

    VAR
      cycle_array_p: ^fst$goi_object_list,
      cycle_number: fst$cycle_number,
      cycle_object_p: ^fst$goi_object,
      cycle_selector: pft$cycle_selector,
      i: integer,
      local_status: ost$status,
      move_object: boolean;

    move_object_info_p^.performance_statistics.file_count :=
          move_object_info_p^.performance_statistics.file_count + 1;
    cycle_selector.cycle_option := pfc$specific_cycle;
    cycle_array_p := file_object_p^.cycle_object_list;

  /move_cycles/
    FOR i := 1 TO UPPERBOUND (cycle_array_p^) DO
      cycle_object_p := ^cycle_array_p^ [i];
      cycle_selector.cycle_number := cycle_object_p^.cycle_number;
      validate_object_move (cycle_object_p, move_object_info_p, move_object);
      move_object_info_p^.performance_statistics.cycle_count :=
            move_object_info_p^.performance_statistics.cycle_count + 1;
      IF move_object THEN
        pfp$r3_physically_move_cycle (path, cycle_selector, move_object_info_p, cycle_number, local_status);
        IF NOT move_object_info_p^.move_status.move_successful THEN
          IF move_object_info_p^.move_status.reason_for_move_failure = pfc$set_threshold_exceeded THEN
            RETURN;
          ELSEIF move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate THEN
            osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_operator_termination, '',
                  local_status);
            display_cycle_move (path, move_object_info_p^, ^cycle_number, display_control, local_status);
            RETURN;
          ELSEIF move_object_info_p^.move_bytes_threshold > 0 THEN
            IF (move_object_info_p^.move_status.reason_for_move_failure = pfc$no_available_space) AND
                  pfp$no_space_movc_dest_volumes (move_object_info_p) THEN
              RETURN;
            ELSE
              CYCLE /move_cycles/
            IFEND;
          IFEND;
        IFEND;
        display_cycle_move (path, move_object_info_p^, ^cycle_number, display_control, local_status);
      IFEND;
    FOREND /move_cycles/;

  PROCEND move_file;

?? OLDTITLE ??
?? NEWTITLE := 'move_hierarchy', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to begin a catalog traversal at the catalog
{   specified by the HIERARCHY parameter.  An attempt is made to move all
{   objects encountered in the traversal that meet the selection criteria of the
{   MOVE_CLASSES command parameters.
{

  PROCEDURE move_hierarchy
    (    path: pft$path;
         move_object_info_p: ^pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      local_status: ost$status,
      object_info_p: ^SEQ ( * ),
      object_segment_pointer: amt$segment_pointer;

    mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, object_segment_pointer, status);
    IF NOT status.normal THEN
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

    RESET object_segment_pointer.sequence_pointer;
    object_info_p := object_segment_pointer.sequence_pointer;

    move_catalog (path, object_info_p, move_object_info_p, display_control, status);

    mmp$delete_scratch_segment (object_segment_pointer, status);
    IF NOT status.normal THEN
      display_abnormal_status (status, display_control, local_status);
      RETURN;
    IFEND;

  PROCEND move_hierarchy;

?? OLDTITLE ??
?? NEWTITLE := 'move_set', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to begin a catalog traversal at the root
{   catalog.  An attempt is made to move all objects encountered in the
{   traversal that meet the selection criteria of the MOVE_CLASSES command
{   parameters.
{

  PROCEDURE move_set
    (    move_object_info_p: ^pft$move_object_info;
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      evaluated_file_reference: fst$evaluated_file_reference,
      family_catalog_object_p: ^fst$goi_object,
      family_catalog_path: array [1 .. 1] of pft$name,
      family_catalog_reference: fst$path,
      family_list_p: ^array [1 .. * ] of ost$name,
      family_object_info_p: ^fst$goi_object_information,
      i: 0 .. 255,
      ignore_status: ost$status,
      local_status: ost$status,
      login_family_in_set: boolean,
      master_catalog_path: array [1 .. 2] of pft$name,
      move_object: boolean,
      number_of_families: 0 .. 255,
      object_index: integer,
      object_info_p: ^SEQ ( * ),
      object_list_p: ^fst$goi_object_list,
      object_segment_pointer: amt$segment_pointer,
      unused_sequence_p: ^SEQ ( * );

    mmp$create_scratch_segment (amc$sequence_pointer, mmc$as_random, object_segment_pointer, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    RESET object_segment_pointer.sequence_pointer;
    object_info_p := object_segment_pointer.sequence_pointer;

    number_of_families := 3;
    REPEAT
      PUSH family_list_p: [1 .. number_of_families];
      pfp$get_families_in_set (move_object_info_p^.set_name, family_list_p^, number_of_families, status);
    UNTIL (NOT status.normal) OR (UPPERBOUND (family_list_p^) >= number_of_families);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF (avp$family_administrator ()) AND (NOT avp$system_administrator ()) THEN
      login_family_in_set := FALSE;
    /check_families/
      FOR i := 1 TO number_of_families DO
        IF family_list_p^ [i] =
              clv$user_identification.family.value (1, clv$user_identification.family.size) THEN
          login_family_in_set := TRUE;
          EXIT /check_families/;
        IFEND;
      FOREND /check_families/;
      IF NOT login_family_in_set THEN
        osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_family_not_in_set,
              clv$user_identification.family.value (1, clv$user_identification.family.size), status);
        osp$append_status_parameter (osc$status_parameter_delimiter, move_object_info_p^.set_name,
              status);
        RETURN;
      IFEND;
    IFEND;

  /process_family/
    FOR i := 1 TO number_of_families DO
      family_catalog_reference := ':';
      family_catalog_reference (2, * ) := family_list_p^ [i];

      IF (avp$family_administrator ()) AND (NOT avp$system_administrator ()) THEN
        IF family_list_p^ [i] <>
              clv$user_identification.family.value (1, clv$user_identification.family.size) THEN
          CYCLE /process_family/;
        IFEND;
      IFEND;

      { Reset the object info scratch segment to the beginning when starting on a new family.

      RESET object_info_p;

      clp$evaluate_file_reference (family_catalog_reference,
            $clt$file_ref_parsing_options [clc$command_file_ref_allowed], {resolve_cycle_number} FALSE,
            evaluated_file_reference, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      pfp$r3_get_object_information (evaluated_file_reference, catalog_information_request,
            {validation_criteria} NIL, object_info_p, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      {
      { Create an adaptable sequence pointer that defines the unused portion of the sequence.
      { PFP$R3_GET_OBJECT_INFORMATION leaves the sequence pointer at the next available byte in the sequence.
      {
      NEXT unused_sequence_p: [[REP #SIZE (object_info_p^) - i#current_sequence_position (object_info_p) OF
            cell]] IN object_info_p;
      RESET unused_sequence_p;

      { Retrieve the master catalog array from the family object info.

      RESET object_info_p;
      NEXT family_object_info_p IN object_info_p;
      family_catalog_object_p := family_object_info_p^.object;
      object_list_p := family_catalog_object_p^.subcatalog_and_file_object_list;

      move_object_info_p^.performance_statistics.catalog_count :=
             move_object_info_p^.performance_statistics.catalog_count + 1;
      validate_object_move (family_catalog_object_p, move_object_info_p, move_object);
      IF move_object THEN
        family_catalog_path [1] := family_list_p^ [i];
        pfp$r3_physically_move_catalog (family_catalog_path, move_object_info_p, local_status);
        IF move_object_info_p^.move_status.move_successful THEN
          display_catalog_move (family_catalog_path, move_object_info_p^, display_control, local_status);
        ELSE
          IF move_object_info_p^.move_status.reason_for_move_failure = pfc$set_threshold_exceeded THEN
            RETURN;
          ELSEIF move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate THEN
            osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$movc_operator_termination, '',
                  local_status);
            display_catalog_move (family_catalog_path, move_object_info_p^, display_control, local_status);
            RETURN;
          ELSEIF move_object_info_p^.move_bytes_threshold > 0 THEN
            IF  (move_object_info_p^.move_status.reason_for_move_failure = pfc$no_available_space) AND
                  pfp$no_space_movc_dest_volumes (move_object_info_p) THEN
              RETURN;
            IFEND;
          ELSE
            display_catalog_move (family_catalog_path, move_object_info_p^, display_control, local_status);
          IFEND;
        IFEND;
      IFEND;

      IF object_list_p = NIL THEN
        RETURN;
      IFEND;

    /process_master_catalog/
      FOR object_index := LOWERBOUND (object_list_p^) TO UPPERBOUND (object_list_p^) DO
        master_catalog_path [1] := family_list_p^ [i];
        master_catalog_path [2] := object_list_p^ [object_index].catalog_name;

        move_catalog (master_catalog_path, unused_sequence_p, move_object_info_p, display_control,
              ignore_status);
        IF (NOT move_object_info_p^.move_status.move_successful) AND
              ((move_object_info_p^.move_status.reason_for_move_failure = pfc$set_threshold_exceeded) OR
              (move_object_info_p^.move_status.reason_for_move_failure = pfc$operator_terminate) OR
              ((move_object_info_p^.move_bytes_threshold > 0) AND
              (move_object_info_p^.move_status.reason_for_move_failure = pfc$no_available_space) AND
              pfp$no_space_movc_dest_volumes (move_object_info_p))) THEN
          EXIT /process_family/;
        IFEND;
      FOREND /process_master_catalog/;
    FOREND /process_family/;

    mmp$delete_scratch_segment (object_segment_pointer, ignore_status);

  PROCEND move_set;

?? OLDTITLE ??
?? NEWTITLE := 'validate_mass_storage_class', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to validate the classes specified by the
{   MASS_STORAGE_CLASSES parameter.

  PROCEDURE validate_mass_storage_class
    (    move_object_info_p: ^pft$move_object_info;
         traverse_set: boolean;
     VAR status: ost$status);

    VAR
      ch: 'A' .. 'Z',
      ch_str: string (52),
      temp_class: dmt$class,
      ms_class_sum: dmt$class,
      pos: 0 .. 255,
      i: integer;

    status.normal := TRUE;

    IF (move_object_info_p^.source_volume_list_p <> NIL) AND
          (move_object_info_p^.move_bytes_threshold = 0) AND traverse_set AND
          (move_object_info_p^.perform_move) THEN
      ms_class_sum := $dmt$class [];
      FOR i := 1 TO UPPERBOUND (move_object_info_p^.source_volume_list_p^) DO
        ms_class_sum := ms_class_sum + move_object_info_p^.source_volume_list_p^ [i]^.ms_class;
      FOREND;

      temp_class := move_object_info_p^.mass_storage_class * ms_class_sum;
      IF temp_class <> $dmt$class [] THEN
        ch_str := '[';
        pos := 2;
        FOR ch := 'A' TO 'Z' DO
          IF ch IN temp_class THEN
            ch_str (pos) := ch;
            ch_str (pos + 1) := ',';
            pos := pos + 2;
          IFEND;
        FOREND;
        pos := pos - 1;
        ch_str (pos) := ']';
        osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$invalid_class_on_source_vol,
              ch_str (1, pos), status);
        RETURN;
      IFEND;
    IFEND;

    IF move_object_info_p^.dest_volume_list_p <> NIL THEN
      IF move_object_info_p^.perform_move THEN
        ms_class_sum := $dmt$class [];
        FOR i := 1 TO UPPERBOUND (move_object_info_p^.dest_volume_list_p^) DO
          ms_class_sum := ms_class_sum + move_object_info_p^.dest_volume_list_p^ [i]^.ms_class;
        FOREND;

        temp_class := move_object_info_p^.mass_storage_class - ms_class_sum;
        IF temp_class <> $dmt$class [] THEN
          ch_str := '[';
          pos := 2;
          FOR ch := 'A' TO 'Z' DO
            IF ch IN temp_class THEN
              ch_str (pos) := ch;
              ch_str (pos + 1) := ',';
              pos := pos + 2;
            IFEND;
          FOREND;
          pos := pos - 1;
          ch_str (pos) := ']';
          osp$set_status_abnormal (pfc$permanent_file_manager_id, pfe$invalid_class_on_dest_vol,
                ch_str (1, pos), status);
          RETURN;
        IFEND;
      ELSE
        FOR i := 1 TO UPPERBOUND (move_object_info_p^.dest_volume_list_p^) DO
          move_object_info_p^.dest_volume_list_p^ [i]^.ms_class := move_object_info_p^.mass_storage_class;
        FOREND;
      IFEND;
    IFEND;

  PROCEND validate_mass_storage_class;

?? OLDTITLE ??
?? NEWTITLE := 'validate_object_move', EJECT ??
{ PURPOSE:
{   The purpose of this procedure is to verify that the specified object is a
{   valid candidate to be moved.
{

  PROCEDURE validate_object_move
    (    object_p: ^fst$goi_object;
         move_object_info_p: ^pft$move_object_info;
     VAR move_object: boolean);

    VAR
      mass_storage_device_info: fst$mass_storage_device_info,
      object_volume_index: ost$positive_integers,
      source_volume_index: ost$positive_integers;

    move_object := FALSE;

    IF (object_p^.object_type = fsc$goi_catalog_object) AND
          (object_p^.catalog_device_information <> NIL) THEN
       mass_storage_device_info := object_p^.catalog_device_information^.mass_storage_device_info;
    ELSEIF (object_p^.object_type = fsc$goi_cycle_object) AND
           (object_p^.cycle_device_class = rmc$mass_storage_device) AND
           (object_p^.cycle_device_information <> NIL) THEN
      mass_storage_device_info := object_p^.cycle_device_information^.mass_storage_device_info;
    ELSE
      RETURN;
    IFEND;

    IF (NOT mass_storage_device_info.resides_online) OR
          (NOT (mass_storage_device_info.mass_storage_class IN move_object_info_p^.mass_storage_class)) THEN
      RETURN;
    IFEND;

    IF (move_object_info_p^.source_volume_list_p <> NIL) AND
          (mass_storage_device_info.volume_list <> NIL) THEN
    /check_object_volume_list/
      FOR object_volume_index := 1 TO UPPERBOUND (mass_storage_device_info.volume_list^) DO
        FOR source_volume_index := 1 TO UPPERBOUND (move_object_info_p^.source_volume_list_p^) DO
          IF (mass_storage_device_info.volume_list^ [object_volume_index].recorded_vsn =
                move_object_info_p^.source_volume_list_p^ [source_volume_index]^.recorded_vsn) THEN
            move_object := TRUE;
            EXIT /check_object_volume_list/;
          IFEND;
        FOREND;
      FOREND /check_object_volume_list/
    IFEND;

  PROCEND validate_object_move;

MODEND pfm$move_object;
