?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Device Management' ??
MODULE dmm$attach_file;
?? RIGHT := 110 ??

{ PURPOSE:
{   Attach device files

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$mainframe_pageable
*copyc mmc$null_shared_queue
*copyc dmd$null_global_file_name
*copyc osd$virtual_address
*copyc amt$access_level
*copyc amt$attribute_source
*copyc amt$average_record_length
*copyc amt$block_type
*copyc amt$collate_table
*copyc amt$collation_value
*copyc amt$data_padding
*copyc amt$error_exit_procedure
*copyc amt$error_limit
*copyc amt$estimated_record_count
*copyc amt$file_access_selections
*copyc amt$file_attribute_keys
*copyc amt$file_attributes
*copyc amt$file_byte_address
*copyc amt$file_identifier
*copyc amt$file_length
*copyc amt$file_limit
*copyc amt$file_organization
*copyc amt$file_position
*copyc amt$forced_write
*copyc amt$global_file_position
*copyc amt$index_padding
*copyc amt$internal_code
*copyc amt$key_length
*copyc amt$key_position
*copyc amt$key_type
*copyc amt$label_exit_procedure
*copyc amt$label_options
*copyc amt$label_type
*copyc amt$local_file_name
*copyc amc$mau_length
*copyc amt$max_block_length
*copyc amt$max_record_length
*copyc amt$message_control
*copyc amt$min_block_length
*copyc amt$min_record_length
*copyc amt$padding_character
*copyc amt$record_limit
*copyc amt$record_type
*copyc amt$records_per_block
*copyc amt$return_option
*copyc amt$user_info
*copyc amt$vertical_print_density
*copyc ost$status
*copyc rmd$volume_declarations
*copyc mme$condition_codes
*copyc dmt$device_file_stored_fmd
*copyc dmt$disk_file_descriptor
*copyc dmt$error_condition_codes
*copyc dmt$existing_sft_entry
*copyc dmt$file_attributes
*copyc dmt$file_descriptor_entry
*copyc dmt$hash_modifiers
*copyc dmt$file_location
*copyc dmt$file_medium_descriptor
*copyc dmt$file_share_history
*copyc dmt$fmd_index
*copyc dmt$global_file_name
*copyc dmt$mainframe_allocation_table
*copyc dmt$ms_volume_directory
*copyc dmt$ms_volume_label
*copyc dmt$segment_file_information
*copyc dmt$stored_fmd
*copyc dmt$stored_ms_fmd_header
*copyc gft$system_file_identifier
*copyc mmt$active_segment_table
*copyc mmt$ast_index
*copyc mmt$page_frame_queue_id
*copyc mmt$rb_ring1_segment_request
*copyc ost$status
*copyc pft$usage_selections
*copyc pft$share_selections
?? POP ??

  PROCEDURE dummy;

*copyc dmv$hash_modifiers
*copyc dmv$hash_modifier_index
  PROCEND dummy;
*copyc gff$old_file_hash
*copyc dmp$build_faus_from_dfl_entry
*copyc dmp$build_fmd_for_existing_file
*copyc dmp$clear_master_attach_lock
*copyc dmp$close_file
*copyc dmp$create_fd_entry
*copyc dmp$create_fmds
*copyc dmp$delete_file_descriptor
*copyc dmp$detach_device_file
*copyc dmp$detach_file
*copyc dmp$determine_queue_status
*copyc dmp$generate_gfn_hash
*copyc dmp$get_active_vol_attributes
*copyc dmp$get_disk_file_descriptor_p
*copyc dmp$get_fau_entry
*copyc dmp$get_fmd_by_index
*copyc dmp$open_directory
*copyc dmp$process_device_log_entry
*copyc dmp$reallocate_file_space
*copyc dmp$search_avt_by_rvsn
*copyc dmp$search_avt_by_vsn
*copyc dmp$search_fdt_by_gfn
*copyc dmp$search_vol_directory_name
*copyc dmp$set_ft_locator_residence
*copyc dmp$set_master_attach_lock
*copyc gfp$get_fde_p
*copyc gfp$get_locked_fde_p
*copyc gfp$unlock_fde_p
*copyc mmp$close_device_file
*copyc mmp$free_pages
*copyc mmp$issue_ring1_segment_request
*copyc mmp$open_file_by_sfid
*copyc mmp$write_modified_pages
*copyc osp$append_status_parameter
*copyc osp$set_status_abnormal
*copyc syp$continue_to_cause
*copyc syp$disestablish_cond_handler
*copyc syp$establish_condition_handler
*copyc dmv$active_volume_table
*copyc dmv$idle_system
*copyc jmv$jcb
*copyc mmv$ast_p
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared By This Module', EJECT ??

  VAR
    dmv$modify_options: [STATIC, READ] pft$usage_selections := $pft$usage_selections
          [pfc$shorten, pfc$append, pfc$modify];

  VAR
    dmv$hash_modifiers: [XDCL, #GATE, READ, STATIC] dmt$hash_modifiers := [
{ Version 0      } 99,
{ Version 1      } 198,
{ unused Versions} REP 256 - 2 of 99];

  VAR
    dmv$hash_modifier_index: [XDCL, #GATE] dmt$hash_modifier_index := 0;

?? OLDTITLE ??
?? NEWTITLE := 'DMP$ATTACH_FILE', EJECT ??
*copy dmh$attach_file

  PROCEDURE [XDCL, #GATE] dmp$attach_file
    (    global_file_name: dmt$global_file_name;
         file_kind: gft$file_kind;
         stored_fmd: dmt$stored_fmd;
         file_usage: pft$usage_selections;
         file_share_selections: pft$share_selections;
         file_history: dmt$file_share_history;
         file_limit: amt$file_limit;
         restricted_attach: boolean;
         exit_on_unknown_file: boolean;
         server_file: boolean;
         shared_queue: mmt$page_frame_queue_id;
     VAR file_damaged: boolean;
     VAR system_file_id: gft$system_file_identifier;
     VAR existing_sft_entry: dmt$existing_sft_entry;
     VAR status: ost$status);

    TYPE
      t$subfile_list = array [1 .. * ] of record
        avt_index: dmt$active_volume_table_index,
        dfl_index: dmt$device_file_list_index,
      recend;

    TYPE
      t$procedure_marker = (clean, master_attach_lock, fde_created, fde_locked, fde_locked_master_clear,
            dfd_built, fmds_built);

    VAR
      aste_p: ^mmt$active_segment_table_entry,
      asti: mmt$ast_index,
      attach_status: ost$status,
      avte_p: ^dmt$ms_active_vol_table_entry,
      avt_index: dmt$active_volume_table_index,
      dfl_index: dmt$device_file_list_index,
      existing_sft_entry_found: boolean,
      fau_lower_bound: dmt$fau_entries,
      fmd_index: dmt$fmd_index,
      fmd_pointer: ost$relative_pointer,
      file_entry_index: gft$file_descriptor_index,
      file_flawed: boolean,
      file_locator: dmt$file_location,
      file_modified: boolean,
      file_table_residence: gft$table_residence,
      flush_status: ost$status,
      fmd_modified: boolean,
      found: boolean,
      ignore_file_info: dmt$file_information,
      internal_vsn: dmt$internal_vsn,
      log_entry: dmt$dl_entry,
      number_fmds: dmt$fmd_index,
      p_dfd: ^dmt$disk_file_descriptor,
      p_dflt: ^dmt$ms_device_file_list_table,
      p_fmd: ^dmt$file_medium_descriptor,
      p_fau: ^dmt$file_allocation_unit,
      p_file_attributes: ^array [1 .. * ] of dmt$file_attribute,
      p_fde: ^gft$file_descriptor_entry,
      p_fmd_seq: ^dmt$stored_fmd,
      p_fmd_version: ^dmt$stored_ms_version_number,
      p_stored_fmd_header: ^dmt$stored_ms_fmd_header,
      p_stored_ms_fmd_subfile: ^dmt$stored_ms_fmd_subfile,
      p_subfile_list: ^t$subfile_list,
      procedure_marker: t$procedure_marker,
      queue_status: gft$queue_status,
      rb: mmt$rb_ring1_segment_request,
      recorded_vsn: rmt$recorded_vsn,
      seg: ost$segment,
      sfid_valid: boolean,
      subfile_count: dmt$fmd_index;

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

    PROCEDURE stored_fmd_condition_handler
      (    mf: ost$monitor_fault;
           p_msa: ^ost$minimum_save_area;
       VAR continue: syt$continue_option);

      VAR
        p_scc: ^syt$system_core_condition,
        p_sac: ^mmt$segment_access_condition,
        ignore: ost$status;

?? NEWTITLE := 'CLEANUP', EJECT ??

      PROCEDURE cleanup;

        CASE procedure_marker OF
        = master_attach_lock =
          dmp$clear_master_attach_lock (system_file_id);
        = fde_created =
          {  'free' fde
          dmp$clear_master_attach_lock (system_file_id);
        = fde_locked =
          {  unlock fde
          {  'free' fde
          dmp$clear_master_attach_lock (system_file_id);
        = fde_locked_master_clear =
          {  unlock fde
          {  'free' fde
        = dfd_built =
          {  free dfd
          {  unlock fde
        = fmds_built =
          {  free fmd
          {  unlock fde
          {  'free' fde
        ELSE
        CASEND;
        IF procedure_marker >= fde_locked THEN
          IF existing_sft_entry = dmc$entry_not_found THEN
            p_fde^.global_file_name := dmv$null_global_file_name;
          IFEND;
        IFEND;

      PROCEND cleanup;
?? OLDTITLE ??
?? EJECT ??

      IF mf.identifier = mmc$segment_fault_processor_id THEN
        p_sac := #LOC (mf.contents);
        CASE p_sac^.identifier OF
        = mmc$sac_io_read_error =
          osp$set_status_abnormal ('MM', mme$io_read_error, 'io error accessing stored fmd - dmp$attach_file',
                status);
          cleanup;
          EXIT dmp$attach_file; {----->
        ELSE
        CASEND;
      ELSEIF mf.identifier = syc$system_core_condition THEN
        p_scc := #LOC (mf.system_core_condition);
        CASE p_scc^.condition OF
        = syc$user_defined_condition =
          IF p_scc^.user_defined_condition = syc$udc_volume_unavailable THEN
            osp$set_status_abnormal ('MM', mme$volume_unavailable,
                  'io error accessing stored fmd - dmp$attach_file', status);
            cleanup;
            EXIT dmp$attach_file; {----->
          IFEND;
        ELSE
        CASEND;
      IFEND;

      syp$continue_to_cause (mf, p_msa, syc$condition_ignored, continue);

    PROCEND stored_fmd_condition_handler;
?? OLDTITLE ??
?? EJECT ??
    IF dmv$idle_system THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
            'system is idle - dmp$attach_file', status);
      RETURN; {----->
    IFEND;

    status.normal := TRUE;
    procedure_marker := clean;
    #SPOIL (procedure_marker);
    existing_sft_entry_found := FALSE;
    existing_sft_entry := dmc$entry_not_found;
    #SPOIL (existing_sft_entry);

  /process_request/
    BEGIN
      dmp$set_ft_locator_residence (file_kind, file_table_residence, file_locator, status);
      IF NOT status.normal THEN
        EXIT /process_request/; {----->
      IFEND;

      p_fmd_seq := ^stored_fmd;
      system_file_id.residence := file_table_residence;

      dmp$determine_queue_status (file_kind, file_usage, file_share_selections, queue_status, status);
      IF NOT status.normal THEN
        EXIT /process_request/; {----->
      IFEND;

      dmp$generate_gfn_hash (global_file_name, system_file_id.file_hash);

      dmp$set_master_attach_lock (system_file_id);

      #SPOIL (procedure_marker);
      procedure_marker := master_attach_lock;
      #SPOIL (procedure_marker);

    /master_attach_lock_set/
      BEGIN

      /see_if_already_attached/
        BEGIN
          dmp$search_fdt_by_gfn (file_table_residence, global_file_name, system_file_id.file_entry_index,
                existing_sft_entry_found);
          IF NOT existing_sft_entry_found THEN
            EXIT /see_if_already_attached/; {----->
          IFEND;

          gfp$get_locked_fde_p (system_file_id, p_fde);

          dmp$get_disk_file_descriptor_p (p_fde, p_dfd);

        /sft_entry_locked/
          BEGIN

{ If this is the first non-restricted attach of a file that was previously
{ restricted attached, then clear the restricted attach field in the
{ file descriptor entry and return to the caller the fact that you
{ encountered a restricted attached file.

            IF p_dfd^.restricted_attach AND (NOT restricted_attach) THEN
              p_dfd^.restricted_attach := FALSE;
              existing_sft_entry := dmc$restricted_attach_entry;
              #SPOIL (existing_sft_entry);
              EXIT /sft_entry_locked/; {----->
            IFEND;

            existing_sft_entry_found := (p_fde^.global_file_name = global_file_name) AND (NOT p_dfd^.purged);

{ verify that the number of fau entries agrees with the allocated_length
            IF existing_sft_entry_found THEN
              number_fmds := p_dfd^.number_of_fmds;
              fau_lower_bound := 1;

              FOR fmd_index := 1 TO number_fmds DO
                dmp$get_fmd_by_index (p_dfd, fmd_index, p_fmd);
                IF (p_fmd = NIL) OR (p_fmd^.volume_assigned AND dmv$active_volume_table.
                      table_p^ [p_fmd^.avt_index].mass_storage.volume_unavailable) THEN
                  IF p_fmd = NIL THEN
                    osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                          'NIL p_fmd - dmm$attach_file', status);
                    EXIT /sft_entry_locked/; {----->
                  ELSE
                    osp$set_status_abnormal (dmc$device_manager_ident, dme$volume_unavailable,
                          dmv$active_volume_table.table_p^ [p_fmd^.avt_index].mass_storage.recorded_vsn,
                          status);
                    EXIT /sft_entry_locked/; {----->
                  IFEND;
                IFEND;
              FOREND;

              existing_sft_entry := dmc$normal_entry;
              #SPOIL (existing_sft_entry);

              IF p_fde^.attach_count = 0 THEN
                p_fde^.queue_status := queue_status;
                IF shared_queue <> mmc$null_shared_queue THEN
                  p_fde^.queue_ordinal := mmc$pq_shared_last_sys + shared_queue;
                ELSE
                  p_fde^.queue_ordinal := mmc$null_shared_queue;
                IFEND;
              IFEND;

              p_fde^.attach_count := p_fde^.attach_count + 1;

              IF (server_file) AND (p_fde^.attach_count > 1) THEN
                asti := p_fde^.asti;
                IF asti <> 0 THEN
                  aste_p := ^mmv$ast_p^ [asti];
                  IF (aste_p^.in_use) AND (aste_p^.sfid = system_file_id) AND
                        (aste_p^.queue_id = mmc$pq_job_working_set) THEN
                    rb.reqcode := syc$rc_ring1_segment_request;
                    rb.request := mmc$sr1_remove_job_shared_pages;
                    rb.system_file_id := system_file_id;
                    rb.server_file := TRUE;
                    rb.status.normal := TRUE;
                    mmp$issue_ring1_segment_request (rb);
                  IFEND;
                IFEND;
              IFEND;

              IF dmv$modify_options * file_usage <> $pft$usage_selections [] THEN

              /log_attach/
                BEGIN
                  p_fde^.attached_in_write_count := 1;
                  dmp$get_fmd_by_index (p_dfd, 1, p_fmd);
                  IF p_fmd = NIL THEN
                    osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                          'No fmd for byte zero - dmp$attach_file.', status);
                    EXIT /log_attach/; {----->
                  IFEND;
                  avt_index := p_fmd^.avt_index;
                  log_entry.kind := dmc$dl_attach_file;
                  log_entry.attach_file_block.global_file_name := global_file_name;
                  log_entry.attach_file_block.dfl_index := p_fmd^.dfl_index;
                  log_entry.attach_file_block.mainframe_assigned := dmv$active_volume_table.
                        table_p^ [avt_index].mass_storage.mainframe_assigned;
                  dmp$process_device_log_entry (avt_index, log_entry, status);

                END /log_attach/;
              IFEND;
            IFEND;

          END /sft_entry_locked/;
          file_damaged := p_dfd^.file_damaged;
          gfp$unlock_fde_p (p_fde);

          IF existing_sft_entry_found OR (NOT status.normal) THEN
            EXIT /master_attach_lock_set/; {----->
          IFEND;
        END /see_if_already_attached/;

{  Exit without attaching the file when the EXIT_ON_UNKNOWN_FILE parameter is TRUE
{  and no entry was found in the system_file_table or the file was attached prior
{  to the point of commitment.

        IF exit_on_unknown_file AND ((existing_sft_entry = dmc$entry_not_found) OR
              (existing_sft_entry = dmc$restricted_attach_entry)) THEN
          EXIT /master_attach_lock_set/; {----->
        IFEND;

{ create new file table entries
        RESET p_fmd_seq;
        NEXT p_fmd_version IN p_fmd_seq;
        IF p_fmd_version = NIL THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$invalid_fmd,
                'No FMD version number - dmp$attach_file.', status);
          EXIT /master_attach_lock_set/; {----->
        IFEND;

        syp$establish_condition_handler (^stored_fmd_condition_handler);

        IF (p_fmd_version^ <> dmc$current_fmd_version) THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$unsupported_fmd_version,
                'Unsupported FMD version number - dmp$attach_file.', status);
          EXIT /master_attach_lock_set/; {----->
        IFEND;

        NEXT p_stored_fmd_header: [p_fmd_version^] IN p_fmd_seq;
        IF p_stored_fmd_header = NIL THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$invalid_fmd,
                'No FMD header - dmp$attach_file.', status);
          EXIT /master_attach_lock_set/; {----->
        IFEND;

        PUSH p_file_attributes: [1 .. 14];

        p_file_attributes^ [1].keyword := dmc$file_hash;
{       p_file_attributes^ [1].file_hash := p_stored_fmd_header^.version_0_0.file_hash;
{For now, we have to take the hash generated from the global file name, as the other might be too small.
        p_file_attributes^ [1].file_hash := system_file_id.file_hash;
        p_file_attributes^ [2].keyword := dmc$file_kind;
        p_file_attributes^ [2].file_kind := p_stored_fmd_header^.version_0_0.file_kind;
        p_file_attributes^ [3].keyword := dmc$preset_value;
        p_file_attributes^ [3].preset_value := p_stored_fmd_header^.version_0_0.preset_value;
        p_file_attributes^ [4].keyword := dmc$clear_space;
        p_file_attributes^ [4].required := p_stored_fmd_header^.version_0_0.clear_space;
        p_file_attributes^ [5].keyword := dmc$file_limit;
        p_file_attributes^ [5].limit := p_stored_fmd_header^.version_0_0.file_limit;
        p_file_attributes^ [6].keyword := dmc$global_file_name;
        p_file_attributes^ [6].global_file_name := global_file_name;
        p_file_attributes^ [7].keyword := dmc$overflow;
        p_file_attributes^ [7].overflow_allowed := p_stored_fmd_header^.version_0_0.overflow_allowed;
        p_file_attributes^ [8].keyword := dmc$requested_allocation_size;
        p_file_attributes^ [8].requested_allocation_size :=
              p_stored_fmd_header^.version_0_0.requested_allocation_size;
        p_file_attributes^ [9].keyword := dmc$requested_transfer_size;
        p_file_attributes^ [9].requested_transfer_size := p_stored_fmd_header^.version_0_0.
              requested_transfer_size;
        p_file_attributes^ [10].keyword := dmc$requested_volume;
        p_file_attributes^ [10].requested_volume := p_stored_fmd_header^.version_0_0.requested_volume;
        p_file_attributes^ [11].keyword := dmc$class;
        p_file_attributes^ [11].class := p_stored_fmd_header^.version_0_0.requested_class;
        p_file_attributes^ [12].keyword := dmc$class_ordinal;
        p_file_attributes^ [12].ordinal := p_stored_fmd_header^.version_0_0.requested_class_ordinal;
        p_file_attributes^ [13].keyword := dmc$write_mode;
        p_file_attributes^ [13].attached_in_write_mode := ((dmv$modify_options * file_usage) <>
              $pft$usage_selections []);
        p_file_attributes^ [14].keyword := dmc$queue_status;
        p_file_attributes^ [14].queue_status := queue_status;

        number_fmds := p_stored_fmd_header^.version_0_0.number_fmds;

        IF number_fmds < 1 THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$invalid_fmd,
                'FMD count less than one - dmp$attach_file.', status);
          EXIT /master_attach_lock_set/; {----->
        IFEND;

{Verify all volumes are available
        PUSH p_subfile_list: [1 .. number_fmds];
        subfile_count := 0;

        FOR fmd_index := 1 TO number_fmds DO
          NEXT p_stored_ms_fmd_subfile: [p_fmd_version^] IN p_fmd_seq;
          IF p_stored_ms_fmd_subfile = NIL THEN
            osp$set_status_abnormal (dmc$device_manager_ident, dme$invalid_fmd,
                  'FMD too small to hold fmds - dmp$attach_file.', status);
            EXIT /master_attach_lock_set/; {----->
          IFEND;
          recorded_vsn := p_stored_ms_fmd_subfile^.version_0_0.recorded_vsn;
          IF (recorded_vsn <> '      ') THEN
            dmp$search_avt_by_vsn (p_stored_ms_fmd_subfile^.version_0_0.internal_vsn, avt_index, found);
            avte_p := ^dmv$active_volume_table.table_p^ [avt_index].mass_storage;
            IF NOT found OR (avte_p^.recorded_vsn <> recorded_vsn) OR
                  NOT (dmc$mainframe_mounted IN avte_p^.status) THEN
              osp$set_status_abnormal (dmc$device_manager_ident, dme$some_volumes_not_online, recorded_vsn,
                    status);
              EXIT /master_attach_lock_set/; {----->
            ELSEIF (avte_p^.volume_unavailable) THEN
              osp$set_status_abnormal (dmc$device_manager_ident, dme$volume_unavailable, recorded_vsn,
                    status);
              EXIT /master_attach_lock_set/; {----->
            IFEND;

            subfile_count := subfile_count + 1;
            p_subfile_list^ [subfile_count].avt_index := avt_index;
            p_subfile_list^ [subfile_count].dfl_index := p_stored_ms_fmd_subfile^.version_0_0.
                  device_file_list_index;
          IFEND;
        FOREND;

        IF (system_file_id.file_hash <> p_stored_fmd_header^.version_0_0.file_hash)
{     } AND (gff$old_file_hash (system_file_id.file_hash) <> gff$old_file_hash (p_stored_fmd_header^.
{         } version_0_0.file_hash)) THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$sfid_fmd_file_hash_mismatch,
                'GFN hash does not match stored_fmd - dmp$attach_file', status);
          EXIT /master_attach_lock_set/; {----->
        IFEND;

        dmp$create_fd_entry (p_file_attributes, system_file_id, status);
        IF NOT status.normal THEN
          EXIT /master_attach_lock_set/; {----->
        IFEND;

        #SPOIL (procedure_marker);
        procedure_marker := fde_created;
        #SPOIL (procedure_marker);

      /file_descriptor_created/
        BEGIN
          gfp$get_locked_fde_p (system_file_id, p_fde);

          #SPOIL (existing_sft_entry);
          #SPOIL (p_fde);
          #SPOIL (procedure_marker);
          procedure_marker := fde_locked;
          #SPOIL (procedure_marker);

        /file_descriptor_locked/
          BEGIN

{           set sft entry to purged to suppress recovery until attach is complete. }

            dmp$get_disk_file_descriptor_p (p_fde, p_dfd);
            p_dfd^.purged := TRUE;

            dmp$clear_master_attach_lock (system_file_id);

            #SPOIL (procedure_marker);
            procedure_marker := fde_locked_master_clear;
            #SPOIL (procedure_marker);


{  If this is a restricted attach, set the field in the disk_file_descriptor
{  to true and set fmd_modified to true to force an update of the stored FMD
{  in the catalog.

            IF restricted_attach THEN
              p_dfd^.restricted_attach := TRUE;
              p_dfd^.fmd_modified := TRUE;
            IFEND;

            dmp$create_fmds (file_locator, subfile_count, p_dfd^);

            #SPOIL (procedure_marker);
            procedure_marker := fmds_built;
            #SPOIL (procedure_marker);

            FOR fmd_index := 1 TO subfile_count DO
              dmp$get_fmd_by_index (p_dfd, fmd_index, p_fmd);
              p_fmd^.in_use := TRUE;
              p_fmd^.dfl_index := p_subfile_list^ [fmd_index].dfl_index;
              avt_index := p_subfile_list^ [fmd_index].avt_index;
              p_fmd^.avt_index := avt_index;
              p_fmd^.internal_vsn := dmv$active_volume_table.table_p^ [avt_index].mass_storage.internal_vsn;
              p_fmd^.volume_assigned := TRUE;
            FOREND;

            syp$disestablish_cond_handler;

            dmp$build_fmd_for_existing_file (p_fde, p_dfd, system_file_id, file_damaged, file_flawed, status);
            IF NOT status.normal THEN
              EXIT /file_descriptor_locked/; {----->
            IFEND;

{ Set sft entry to NOT purged to enable recovery.                      }

            p_dfd^.purged := FALSE;

            IF p_fde^.attached_in_write_count > 0 THEN
              dmp$get_fmd_by_index (p_dfd, 1, p_fmd);
              IF (p_fmd = NIL) THEN
                osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                      'No fmd for byte zero - dmp$attach_file.', status);
                EXIT /file_descriptor_locked/; {----->
              IFEND;

              log_entry.kind := dmc$dl_attach_file;
              log_entry.attach_file_block.global_file_name := global_file_name;
              log_entry.attach_file_block.dfl_index := p_fmd^.dfl_index;
              log_entry.attach_file_block.mainframe_assigned := dmv$active_volume_table.
                    table_p^ [p_fmd^.avt_index].mass_storage.mainframe_assigned;
              dmp$process_device_log_entry (p_fmd^.avt_index, log_entry, status);
              IF NOT status.normal THEN
                EXIT /file_descriptor_locked/; {----->
              IFEND;
            IFEND;

            IF shared_queue <> mmc$null_shared_queue THEN
              p_fde^.queue_ordinal := mmc$pq_shared_last_sys + shared_queue;
            ELSE
              p_fde^.queue_ordinal := mmc$null_shared_queue;
            IFEND;

            gfp$unlock_fde_p (p_fde);

            IF file_flawed THEN
              dmp$reallocate_file_space (system_file_id, TRUE, status);

{ Open a segment for the file, so that the page can be written to the new allocation unit.
{ Any pages modified by the reallocate MUST be flushed to disk.  The write must be done now;
{ if the file is being attached for read only, pages will not be written when the file is detached.

              mmp$open_file_by_sfid (system_file_id, 1, 1, mmc$as_random, mmc$sar_write_extend, seg,
                    flush_status);
              IF flush_status.normal THEN
                mmp$write_modified_pages (#ADDRESS (1, seg, 0), 7ffffff0(16), osc$wait, flush_status);
                IF NOT flush_status.normal THEN
                  mmp$free_pages (#ADDRESS (1, seg, 0), 7ffffff0(16), osc$wait, flush_status);
                IFEND;
                mmp$close_device_file (seg, flush_status);
              IFEND;

              status.normal := TRUE; { Allow a file with un-recovered read error to be attached. }
            IFEND;

            EXIT /process_request/; { <-------------------<<< NORMAL EXIT <---------------<<< }

          END /file_descriptor_locked/;

          gfp$unlock_fde_p (p_fde);

        END /file_descriptor_created/;

        {Attach has failed.
        {Attempt detach of file.  Note that this may log a detach log entry for a
        {file that never had an attach log entry issued for it - logger allows this.
        {Must clear purged flag to avoid destroying the file.
        {Must go thru detach to increment delete_count and decrement attach_count.

        IF existing_sft_entry = dmc$entry_not_found THEN
          {fde was being created by this attach
          {No human yet born understands how to cleanup in all of these cases
          p_fde^.global_file_name := dmv$null_global_file_name;
        ELSE
          p_dfd^.purged := FALSE;
          dmp$detach_file (system_file_id, {access_allowed} FALSE, {flush_pages} FALSE,
                dmc$df_ignore_file_info, file_modified, fmd_modified, ignore_file_info, attach_status);
          IF attach_status.normal THEN
            dmp$delete_file_descriptor (system_file_id, attach_status);
          IFEND;
        IFEND;

        EXIT /process_request/; {----->

      END /master_attach_lock_set/;

      dmp$clear_master_attach_lock (system_file_id);

    END /process_request/;

  PROCEND dmp$attach_file;
?? TITLE := '  dmp$attach_device_file', EJECT ??

  PROCEDURE [XDCL, #GATE] dmp$attach_device_file
    (    recorded_vsn: rmt$recorded_vsn;
         user_supplied_df_name: ost$name;
     VAR system_file_id: gft$system_file_identifier;
     VAR status: ost$status);

    VAR
      avt_index: dmt$active_volume_table_index,
      active_vol_attributes: array [1 .. 4] of dmt$assigned_ms_vol_attribute,
      volume_active: boolean;

    IF dmv$idle_system THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
            'system is idle - dmp$attach_device_file', status);
      RETURN; {----->
    IFEND;

    status.normal := TRUE;

    avt_index := 0;
    active_vol_attributes [1].keyword := dmc$ms_volume_directory;
    active_vol_attributes [2].keyword := dmc$ms_device_file_list_table;
    active_vol_attributes [3].keyword := dmc$ms_device_allocation_table;
    active_vol_attributes [4].keyword := dmc$avt_index;

    dmp$get_active_vol_attributes (recorded_vsn, 0, active_vol_attributes, volume_active);
    IF NOT volume_active THEN
      {
      { issue mount request
      {
      osp$set_status_abnormal (dmc$device_manager_ident, dme$avt_entry_not_found, 'volume not in avt',
            status);
      RETURN; {----->
    IFEND;

    avt_index := active_vol_attributes [4].index;

    dmp$attach_volume_device_file (user_supplied_df_name, active_vol_attributes [1].directory_sfid,
          active_vol_attributes [2].p_dflt, active_vol_attributes [3].p_dat, avt_index, system_file_id,
          status);

  PROCEND dmp$attach_device_file;
?? TITLE := '  dmp$attach_volume_device_file', EJECT ??

  PROCEDURE [XDCL] dmp$attach_volume_device_file
    (    user_supplied_name: ost$name;
         directory_sfid: gft$system_file_identifier;
         dflt_sfid: gft$system_file_identifier;
         dat_sfid: gft$system_file_identifier;
         avt_index: dmt$active_volume_table_index;
     VAR system_file_id: gft$system_file_identifier;
     VAR status: ost$status);

    VAR
      attach_status: ost$status,
      dfl_index: dmt$device_file_list_index,
      directory_index: dmt$directory_index,
      entry_found: boolean,
      file_already_attached: boolean,
      file_damaged: boolean,
      file_flawed: boolean,
      file_modified: boolean,
      fmd_modified: boolean,
      global_file_name: dmt$global_file_name,
      p_dfd: ^dmt$disk_file_descriptor,
      p_fmd: ^dmt$file_medium_descriptor,
      p_fde: ^gft$file_descriptor_entry,
      p_directory: ^dmt$ms_volume_directory,
      p_fmd_version: ^dmt$stored_ms_version_number,
      p_stored_fmd: ^dmt$device_file_stored_fmd,
      p_stored_fmd_header: ^dmt$stored_ms_fmd_header,
      p_stored_fmd_subfile: ^dmt$stored_ms_fmd_subfile,
      stored_df_fmd: dmt$device_file_stored_fmd;

    status.normal := TRUE;

    directory_index := 0;
    dmp$search_vol_directory_name (user_supplied_name, directory_sfid, directory_index, entry_found, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;
    IF NOT entry_found THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$unknown_device_file,
            'Unknown device_file - dmp$attach_volume_device_file.', status);
      osp$append_status_parameter (' ', user_supplied_name, status);
      RETURN; {----->
    IFEND;

    dmp$open_directory (directory_sfid, osc$os_ring_1, osc$tsrv_ring, mmc$sar_read, mmc$as_sequential,
          p_directory, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    stored_df_fmd := p_directory^.entries [directory_index].stored_df_fmd;
    global_file_name := p_directory^.entries [directory_index].global_file_name;

    dmp$close_file (p_directory, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    p_stored_fmd := ^stored_df_fmd;
    RESET p_stored_fmd;

    NEXT p_fmd_version IN p_stored_fmd;
    IF p_fmd_version = NIL THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$invalid_fmd,
            'No FMD version number - dmp$attach_volume_device_file.', status);
      osp$append_status_parameter (' ', user_supplied_name, status);
      RETURN; {----->
    IFEND;

    IF (p_fmd_version^ <> dmc$current_fmd_version) THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$unsupported_fmd_version,
            'Unsupported FMD version number - dmp$attach_volume_device_file.', status);
      osp$append_status_parameter (' ', user_supplied_name, status);
      RETURN; {----->
    IFEND;

    NEXT p_stored_fmd_header: [dmc$current_fmd_version] IN p_stored_fmd;
    IF p_stored_fmd_header = NIL THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$invalid_fmd,
            'No FMD header - dmp$attach_volume_device_file.', status);
      osp$append_status_parameter (' ', user_supplied_name, status);
      RETURN; {----->
    IFEND;

    NEXT p_stored_fmd_subfile: [dmc$current_fmd_version] IN p_stored_fmd;
    IF p_stored_fmd_subfile = NIL THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$invalid_fmd,
            'FMD too small to hold subfiles - dmp$attach_volume_device_file.', status);
      osp$append_status_parameter (' ', user_supplied_name, status);
      RETURN; {----->
    IFEND;

    { In systems with two byte DFL indexes (1.5.2 and earlier) the byte_address field of
    { the stored FMD subfile was not initialized properly for the label (i.e. it contains
    { stack garbage).  Since systems with three byte DFL indexes use the low byte of the
    { old byte_address field as the high byte of the DFL index, an invalid DFL index might
    { be used for the label unless it is fixed here.

    IF (directory_index = dmc$label_directory_index) THEN
      p_stored_fmd_subfile^.version_0_0.stored_byte_address := 0;
      p_stored_fmd_subfile^.version_0_0.device_file_list_index := dmc$label_dfl_index;
    IFEND;

    dfl_index := p_stored_fmd_subfile^.version_0_0.device_file_list_index;

    dmp$attach_device_file_by_fmd (global_file_name, stored_df_fmd, file_already_attached, system_file_id,
          status);
    IF file_already_attached OR (NOT status.normal) THEN
      RETURN; {----->
    IFEND;

    gfp$get_locked_fde_p (system_file_id, p_fde);
    dmp$get_disk_file_descriptor_p (p_fde, p_dfd);
    dmp$build_fmd_for_existing_file (p_fde, p_dfd, system_file_id, file_damaged, file_flawed, status);
    gfp$unlock_fde_p (p_fde);
    IF NOT status.normal THEN
      dmp$detach_device_file (system_file_id, file_modified, fmd_modified, attach_status);
    IFEND;

  PROCEND dmp$attach_volume_device_file;
?? TITLE := '  dmp$attach_device_file_by_fmd', EJECT ??

  PROCEDURE [XDCL] dmp$attach_device_file_by_fmd
    (    global_file_name: dmt$global_file_name;
         stored_ms_device_file_fmd: dmt$device_file_stored_fmd;
     VAR file_already_attached: boolean;
     VAR system_file_id: gft$system_file_identifier;
     VAR status: ost$status);

    VAR
      attach_status: ost$status,
      dfl_index: dmt$device_file_list_index,
      file_locator: dmt$file_location,
      file_modified: boolean,
      file_kind: gft$file_kind,
      file_usage: pft$usage_selections,
      file_share_history: dmt$file_share_history,
      file_share_selections: pft$share_selections,
      fmd_modified: boolean,
      fmd_pointer: ost$relative_pointer,
      internal_vsn: dmt$internal_vsn,
      p_dfd: ^dmt$disk_file_descriptor,
      p_file_attributes: ^array [1 .. * ] of dmt$file_attribute,
      p_fde: ^gft$file_descriptor_entry,
      p_fmd: ^dmt$file_medium_descriptor,
      p_fmd_version: ^dmt$stored_ms_version_number,
      p_stored_fmd: ^dmt$device_file_stored_fmd,
      p_stored_fmd_header: ^dmt$stored_ms_fmd_header,
      p_stored_fmd_subfile: ^dmt$stored_ms_fmd_subfile;

    status.normal := TRUE;

  /process_request/
    BEGIN
      file_already_attached := FALSE;

      p_stored_fmd := ^stored_ms_device_file_fmd;
      RESET p_stored_fmd;

      NEXT p_fmd_version IN p_stored_fmd;
      IF p_fmd_version = NIL THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'no stored fmd version number - DMMATCH', status);
        EXIT /process_request/; {----->
      IFEND;

      NEXT p_stored_fmd_header: [0] IN p_stored_fmd;
      IF p_stored_fmd_header = NIL THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'unable to get fmd header - DMMATCH', status);
        EXIT /process_request/; {----->
      IFEND;

      file_kind := gfc$fk_device_file;
      file_usage := $pft$usage_selections [pfc$read];
      file_share_selections := $pft$share_selections [];
      file_share_history := dmc$minimum_file_share_his;
      dmp$set_ft_locator_residence (file_kind, system_file_id.residence, file_locator, status);
      IF NOT status.normal THEN
        EXIT /process_request/; {----->
      IFEND;

      dmp$generate_gfn_hash (global_file_name, system_file_id.file_hash);

    /validate_sfid/
      BEGIN
        IF (system_file_id.file_hash <> p_stored_fmd_header^.version_0_0.file_hash)
{     } AND (gff$old_file_hash (system_file_id.file_hash) <> gff$old_file_hash (p_stored_fmd_header^.
{         } version_0_0.file_hash)) THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$inconsistent_hash_and_gfn,
                'file hash global file name mismatch - DMMATCH', status);
          EXIT /process_request/; {----->
        IFEND;
      END /validate_sfid/;

      dmp$set_master_attach_lock (system_file_id);

    /master_attach_lock_set/
      BEGIN

      /locate_fde/
        BEGIN
          dmp$search_fdt_by_gfn (system_file_id.residence, global_file_name, system_file_id.file_entry_index,
                file_already_attached);
          IF NOT file_already_attached THEN
            EXIT /locate_fde/; {----->
          IFEND;

        /existing_fde_found/
          BEGIN
            gfp$get_locked_fde_p (system_file_id, p_fde);
            dmp$get_disk_file_descriptor_p (p_fde, p_dfd);

            file_already_attached := (p_fde^.global_file_name = global_file_name) AND (NOT p_dfd^.purged);
            IF file_already_attached THEN
              p_fde^.attach_count := p_fde^.attach_count + 1;
            IFEND;

          END /existing_fde_found/;
          gfp$unlock_fde_p (p_fde);

        END /locate_fde/;

        IF file_already_attached THEN
          EXIT /master_attach_lock_set/; {----->
        IFEND;

        NEXT p_stored_fmd_subfile: [0] IN p_stored_fmd;
        IF p_stored_fmd_subfile = NIL THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                'unable to get stored fmd subfiles', status);
          EXIT /master_attach_lock_set/; {----->
        IFEND;

{ create new file table entries
        CASE p_fmd_version^ OF
        = 0 =
          PUSH p_file_attributes: [1 .. 12];

          p_file_attributes^ [1].keyword := dmc$file_hash;
{         p_file_attributes^ [1].file_hash := p_stored_fmd_header^.version_0_0.file_hash;
{For now, we have to take the hash generated from the global file name, as the other might be too small.
          p_file_attributes^ [1].file_hash := system_file_id.file_hash;
          p_file_attributes^ [2].keyword := dmc$file_kind;
          p_file_attributes^ [2].file_kind := p_stored_fmd_header^.version_0_0.file_kind;
          p_file_attributes^ [3].keyword := dmc$preset_value;
          p_file_attributes^ [3].preset_value := p_stored_fmd_header^.version_0_0.preset_value;
          p_file_attributes^ [4].keyword := dmc$clear_space;
          p_file_attributes^ [4].required := p_stored_fmd_header^.version_0_0.clear_space;
          p_file_attributes^ [5].keyword := dmc$file_limit;
          p_file_attributes^ [5].limit := p_stored_fmd_header^.version_0_0.file_limit;
          p_file_attributes^ [6].keyword := dmc$global_file_name;
          p_file_attributes^ [6].global_file_name := global_file_name;
          p_file_attributes^ [7].keyword := dmc$overflow;
          p_file_attributes^ [7].overflow_allowed := p_stored_fmd_header^.version_0_0.overflow_allowed;
          p_file_attributes^ [8].keyword := dmc$requested_allocation_size;
          p_file_attributes^ [8].requested_allocation_size :=
                p_stored_fmd_header^.version_0_0.requested_allocation_size;
          p_file_attributes^ [9].keyword := dmc$requested_transfer_size;
          p_file_attributes^ [9].requested_transfer_size := p_stored_fmd_header^.version_0_0.
                requested_transfer_size;
          p_file_attributes^ [10].keyword := dmc$requested_volume;
          p_file_attributes^ [10].requested_volume := p_stored_fmd_header^.version_0_0.requested_volume;
          p_file_attributes^ [11].keyword := dmc$class;
          p_file_attributes^ [11].class := p_stored_fmd_header^.version_0_0.requested_class;
          p_file_attributes^ [12].keyword := dmc$class_ordinal;
          p_file_attributes^ [12].ordinal := p_stored_fmd_header^.version_0_0.requested_class_ordinal;
          dfl_index := p_stored_fmd_subfile^.version_0_0.device_file_list_index;
          internal_vsn := p_stored_fmd_subfile^.version_0_0.internal_vsn;
        ELSE
          osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                'bad fmd version number - DMMATCH', status);
          EXIT /master_attach_lock_set/; {----->
        CASEND;

        dmp$create_fd_entry (p_file_attributes, system_file_id, status);
        IF NOT status.normal THEN
          EXIT /master_attach_lock_set/; {----->
        IFEND;

      /file_descriptor_created/
        BEGIN
          gfp$get_locked_fde_p (system_file_id, p_fde);
          IF p_fde = NIL THEN
            dmp$clear_master_attach_lock (system_file_id);
            EXIT /file_descriptor_created/; {----->
          IFEND;

        /file_descriptor_locked/
          BEGIN

            dmp$clear_master_attach_lock (system_file_id);

            dmp$get_disk_file_descriptor_p (p_fde, p_dfd);
            dmp$create_fmds (file_locator, 1, p_dfd^);

            dmp$get_fmd_by_index (p_dfd, 1, p_fmd);
            p_fmd^.in_use := TRUE;
            p_fmd^.dfl_index := dfl_index;
            p_fmd^.internal_vsn := internal_vsn;
            p_fmd^.volume_assigned := TRUE;

          END /file_descriptor_locked/;
          gfp$unlock_fde_p (p_fde);

          IF status.normal THEN
            EXIT /process_request/; {----->
          IFEND;

        END /file_descriptor_created/;

        dmp$detach_device_file (system_file_id, file_modified, fmd_modified, attach_status);
        EXIT /process_request/; {----->

      END /master_attach_lock_set/;

      dmp$clear_master_attach_lock (system_file_id);

    END /process_request/;

  PROCEND dmp$attach_device_file_by_fmd;

?? TITLE := '  dmp$attach_directory_from_label', EJECT ??

  PROCEDURE [XDCL] dmp$attach_directory_from_label
    (VAR volume_label: {input} dmt$ms_volume_label;
         dat_sfid: gft$system_file_identifier;
     VAR directory_sfid: gft$system_file_identifier;
     VAR status: ost$status);

    VAR
      able_to_locate_fde: boolean,
      allocated_length_in_bytes: amt$file_byte_address,
      attach_status: ost$status,
      avt_index: dmt$active_volume_table_index,
      daus_per_allocation_unit: dmt$daus_per_allocation,
      directory_stored_df_fmd: dmt$device_file_stored_fmd,
      eof_byte_address: amt$file_byte_address,
      eoi_byte_address: amt$file_byte_address,
      file_already_attached: boolean,
      file_flawed: boolean,
      file_modified: boolean,
      fmd_modified: boolean,
      global_file_name: dmt$global_file_name,
      p_directory_fmd_header: ^dmt$stored_ms_fmd_header,
      p_directory_fmd_subfile: ^dmt$stored_ms_fmd_subfile,
      p_directory_fmd_version: ^dmt$stored_ms_version_number,
      p_dfd: ^dmt$disk_file_descriptor,
      p_fde: ^gft$file_descriptor_entry,
      p_fmd: ^dmt$file_medium_descriptor,
      p_stored_directory_fmd: ^dmt$device_file_stored_fmd,
      p_volume_label: ^dmt$ms_volume_label,
      p_volume_label_header: ^dmt$volume_label_header,
      p_volume_label_0_0: ^dmt$ms_label_0_0,
      stored_directory_dfl_entry: dmt$ms_device_file_list_entry,
      volume_active: boolean;

    status.normal := TRUE;

  /process_request/
    BEGIN
      allocated_length_in_bytes := 0;
      p_volume_label := ^volume_label;

      RESET p_volume_label;

      NEXT p_volume_label_header IN p_volume_label;
      IF p_volume_label_header = NIL THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'p_volume_label_header = NIL -DMMATCH', status);
        EXIT /process_request/; {----->
      IFEND;

      dmp$search_avt_by_rvsn (p_volume_label_header^.recorded_vsn, avt_index, volume_active);
      IF NOT volume_active THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$avt_entry_not_found, 'volume not in avt',
              status);
        EXIT /process_request/; {----->
      IFEND;

      CASE p_volume_label_header^.version_number OF
      = dmc$ms_label_0_0 =
        NEXT p_volume_label_0_0 IN p_volume_label;
        IF p_volume_label_0_0 = NIL THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                'p_volume_label_0_0 = NIL - DMMATCH', status);
          EXIT /process_request/; {----->
        IFEND;
        stored_directory_dfl_entry := p_volume_label_0_0^.directory_dfl_entry;
        directory_stored_df_fmd := p_volume_label_0_0^.directory_fmd;
      ELSE
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'label version not supported', status);
        EXIT /process_request/; {----->
      CASEND;

      daus_per_allocation_unit := stored_directory_dfl_entry.daus_per_allocation_unit;
      global_file_name := stored_directory_dfl_entry.global_file_name;
      allocated_length_in_bytes := stored_directory_dfl_entry.fmd_length;
      eof_byte_address := stored_directory_dfl_entry.end_of_file;
      eoi_byte_address := stored_directory_dfl_entry.end_of_information;

      PUSH p_stored_directory_fmd;

      RESET p_stored_directory_fmd;

      p_stored_directory_fmd^ := directory_stored_df_fmd;

      RESET p_stored_directory_fmd;

      NEXT p_directory_fmd_version IN p_stored_directory_fmd;

      NEXT p_directory_fmd_header: [0] IN p_stored_directory_fmd;

      NEXT p_directory_fmd_subfile: [0] IN p_stored_directory_fmd;

      CASE p_directory_fmd_version^ OF
      = 0 =
        p_directory_fmd_subfile^.version_0_0.device_file_list_index := dmc$directory_dfl_index;
        p_directory_fmd_subfile^.version_0_0.internal_vsn := p_volume_label_header^.internal_vsn;
        p_directory_fmd_subfile^.version_0_0.recorded_vsn := p_volume_label_header^.recorded_vsn;
      ELSE
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'unsupported fmd version', status);
        EXIT /process_request/; {----->
      CASEND;

      dmp$attach_device_file_by_fmd (global_file_name, p_stored_directory_fmd^, file_already_attached,
            directory_sfid, status);
      IF NOT status.normal THEN
        EXIT /process_request/; {----->
      IFEND;
      IF file_already_attached THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$duplicate_device_file_gfn,
              'directory df gfn already used', status);
        EXIT /process_request/; {----->
      IFEND;

    /directory_attached/
      BEGIN
        gfp$get_fde_p (directory_sfid, p_fde);
        p_fde^.eoi_byte_address := eoi_byte_address;
        dmp$get_disk_file_descriptor_p (p_fde, p_dfd);
        dmp$get_fmd_by_index (p_dfd, 1, p_fmd);
        p_fmd^.avt_index := avt_index;
        dmp$build_faus_from_dfl_entry (dat_sfid, stored_directory_dfl_entry, p_fmd, p_dfd, directory_sfid, 1,
              file_flawed, status);
        IF NOT status.normal THEN
          EXIT /directory_attached/; {----->
        IFEND;

        EXIT /process_request/; {----->

      END /directory_attached/;

      dmp$detach_device_file (directory_sfid, file_modified, fmd_modified, attach_status);

    END /process_request/;

  PROCEND dmp$attach_directory_from_label;
?? TITLE := '  dmp$attach_dat_from_label', EJECT ??

  PROCEDURE [XDCL] dmp$attach_dat_from_label
    (VAR volume_label: {input} dmt$ms_volume_label;
         avt_index: dmt$active_volume_table_index;
     VAR dat_sfid: gft$system_file_identifier;
     VAR status: ost$status);

?? PUSH (LISTEXT := ON) ??
*copy dmp$store_existing_df_fat
?? POP ??

    VAR
      able_to_locate_fde: boolean,
      allocated_length_in_bytes: amt$file_byte_address,
      attach_status: ost$status,
      dat_global_file_name: dmt$global_file_name,
      dat_stored_df_fmd: dmt$device_file_stored_fmd,
      eof_byte_address: amt$file_byte_address,
      eoi_byte_address: amt$file_byte_address,
      file_already_attached: boolean,
      file_modified: boolean,
      fmd_modified: boolean,
      number_faus: dmt$fau_entries,
      p_device_allocation_table_fat: ^dmt$stored_ms_device_file_fat,
      p_dfd: ^dmt$disk_file_descriptor,
      p_fde: ^gft$file_descriptor_entry,
      p_fmd: ^dmt$file_medium_descriptor,
      p_volume_label: ^dmt$ms_volume_label,
      p_volume_label_header: ^dmt$volume_label_header,
      p_volume_label_0_0: ^dmt$ms_label_0_0,
      p_stored_df_fat_header: ^dmt$stored_df_fat_header,
      stored_dat_dfl_entry: dmt$ms_device_file_list_entry;

    status.normal := TRUE;

  /process_request/
    BEGIN
      p_volume_label := ^volume_label;

      RESET p_volume_label;

      NEXT p_volume_label_header IN p_volume_label;
      IF p_volume_label_header = NIL THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'p_volume_label_header = NIL -DMMATCH', status);
        EXIT /process_request/; {----->
      IFEND;

      CASE p_volume_label_header^.version_number OF
      = dmc$ms_label_0_0 =
        NEXT p_volume_label_0_0 IN p_volume_label;
        IF p_volume_label_0_0 = NIL THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                'p_volume_label_0_0 = NIL - DMMATCH', status);
          EXIT /process_request/; {----->
        IFEND;
        dat_stored_df_fmd := p_volume_label_0_0^.device_allocation_table_fmd;
        stored_dat_dfl_entry := p_volume_label_0_0^.dat_dfl_entry;
        dat_global_file_name := stored_dat_dfl_entry.global_file_name;
        allocated_length_in_bytes := stored_dat_dfl_entry.fmd_length;
        eof_byte_address := stored_dat_dfl_entry.end_of_file;
        eoi_byte_address := stored_dat_dfl_entry.end_of_information;
        NEXT p_stored_df_fat_header IN p_volume_label;
        IF p_stored_df_fat_header = NIL THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                'p_stored_df_fat_header = NIL - DMMATCH', status);
          EXIT /process_request/; {----->
        IFEND;
        number_faus := p_stored_df_fat_header^.number_faus;
        RESET p_volume_label TO p_stored_df_fat_header;
        NEXT p_device_allocation_table_fat: [1 .. number_faus] IN p_volume_label;
        IF p_device_allocation_table_fat = NIL THEN
          osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
                'p_device_allocation_table_fat = NIL - DMMATCH', status);
          EXIT /process_request/; {----->
        IFEND;
      ELSE
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'unsupported label version number', status);
        EXIT /process_request/; {----->
      CASEND;

      dmp$attach_device_file_by_fmd (dat_global_file_name, dat_stored_df_fmd, file_already_attached, dat_sfid,
            status);
      IF NOT status.normal THEN
        EXIT /process_request/; {----->
      IFEND;
      IF file_already_attached THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$duplicate_device_file_gfn,
              'dat df gfn already used', status);
        EXIT /process_request/; {----->
      IFEND;

    /dat_attached/
      BEGIN
        gfp$get_fde_p (dat_sfid, p_fde);
        p_fde^.eoi_byte_address := eoi_byte_address;
        dmp$get_disk_file_descriptor_p (p_fde, p_dfd);
        dmp$get_fmd_by_index (p_dfd, 1, p_fmd);
        p_fmd^.avt_index := avt_index;

        dmp$store_existing_df_fat (dat_sfid, p_device_allocation_table_fat, status);
        IF status.normal THEN
          EXIT /process_request/; {----->
        IFEND;

      END /dat_attached/;
      dmp$detach_device_file (dat_sfid, file_modified, fmd_modified, attach_status);

    END /process_request/;

  PROCEND dmp$attach_dat_from_label;
?? TITLE := '  dmp$attach_dflt_from_label', EJECT ??

  PROCEDURE [XDCL] dmp$attach_dflt_from_label
    (VAR volume_label: {input} dmt$ms_volume_label;
         dat_sfid: gft$system_file_identifier;
     VAR dflt_sfid: gft$system_file_identifier;
     VAR status: ost$status);

    VAR
      attach_status: ost$status,
      avt_index: dmt$active_volume_table_index,
      file_already_attached: boolean,
      file_flawed: boolean,
      dflt_stored_df_fmd: dmt$device_file_stored_fmd,
      dflt_global_file_name: dmt$global_file_name,
      eoi_byte_address: amt$file_byte_address,
      file_modified: boolean,
      fmd_modified: boolean,
      p_dfd: ^dmt$disk_file_descriptor,
      p_fde: ^gft$file_descriptor_entry,
      p_fmd: ^dmt$file_medium_descriptor,
      p_stored_dfl_fmd_version: ^dmt$stored_ms_version_number,
      p_stored_dfl_fmd: ^dmt$device_file_stored_fmd,
      p_stored_dfl_fmd_header: ^dmt$stored_ms_fmd_header,
      p_stored_dfl_fmd_subfile: ^dmt$stored_ms_fmd_subfile,
      p_volume_label: ^dmt$ms_volume_label,
      p_volume_label_header: ^dmt$volume_label_header,
      p_volume_label_0_0: ^dmt$ms_label_0_0,
      stored_dfl_dfl_entry: dmt$ms_device_file_list_entry,
      volume_active: boolean;

    status.normal := TRUE;

    p_volume_label := ^volume_label;

    RESET p_volume_label;

    NEXT p_volume_label_header IN p_volume_label;
    IF p_volume_label_header = NIL THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
            'p_volume_label_header = NIL -DMMATCH', status);
      RETURN; {----->
    IFEND;

    dmp$search_avt_by_rvsn (p_volume_label_header^.recorded_vsn, avt_index, volume_active);
    IF NOT volume_active THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$avt_entry_not_found, 'volume not in avt',
            status);
      RETURN; {----->
    IFEND;

    CASE p_volume_label_header^.version_number OF
    = dmc$ms_label_0_0 =
      NEXT p_volume_label_0_0 IN p_volume_label;
      IF p_volume_label_0_0 = NIL THEN
        osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
              'p_volume_label_0_0 = NIL - DMMATCH', status);
        RETURN; {----->
      IFEND;
      dflt_stored_df_fmd := p_volume_label_0_0^.device_file_list_fmd;
      stored_dfl_dfl_entry := p_volume_label_0_0^.device_file_list_dfl_entry;
    ELSE
      osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file,
            'unsupported label version number', status);
      RETURN; {----->
    CASEND;

    dflt_global_file_name := stored_dfl_dfl_entry.global_file_name;
    eoi_byte_address := stored_dfl_dfl_entry.end_of_information;

    PUSH p_stored_dfl_fmd;
    p_stored_dfl_fmd^ := dflt_stored_df_fmd;
    RESET p_stored_dfl_fmd;
    NEXT p_stored_dfl_fmd_version IN p_stored_dfl_fmd;
    NEXT p_stored_dfl_fmd_header: [0] IN p_stored_dfl_fmd;
    NEXT p_stored_dfl_fmd_subfile: [0] IN p_stored_dfl_fmd;

    CASE p_stored_dfl_fmd_version^ OF
    = 0 =
      p_stored_dfl_fmd_subfile^.version_0_0.device_file_list_index := dmc$device_file_list_dfl_index;
      p_stored_dfl_fmd_subfile^.version_0_0.internal_vsn := p_volume_label_header^.internal_vsn;
      p_stored_dfl_fmd_subfile^.version_0_0.recorded_vsn := p_volume_label_header^.recorded_vsn;
    ELSE
      osp$set_status_abnormal (dmc$device_manager_ident, dme$unable_to_attach_file, 'unsupported fmd version',
            status);
      RETURN; {----->
    CASEND;

    dmp$attach_device_file_by_fmd (dflt_global_file_name, dflt_stored_df_fmd, file_already_attached,
          dflt_sfid, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;
    IF file_already_attached THEN
      osp$set_status_abnormal (dmc$device_manager_ident, dme$duplicate_device_file_gfn,
            'dflt df gfn already used', status);
      RETURN; {----->
    IFEND;

    gfp$get_fde_p (dflt_sfid, p_fde);
    p_fde^.eoi_byte_address := eoi_byte_address;
    dmp$get_disk_file_descriptor_p (p_fde, p_dfd);
    dmp$get_fmd_by_index (p_dfd, 1, p_fmd);
    p_fmd^.avt_index := avt_index;

    dmp$build_faus_from_dfl_entry (dat_sfid, stored_dfl_dfl_entry, p_fmd, p_dfd, dflt_sfid, 1, file_flawed,
          status);
    IF NOT status.normal THEN
      dmp$detach_device_file (dflt_sfid, file_modified, fmd_modified, attach_status);
    IFEND;

  PROCEND dmp$attach_dflt_from_label;
MODEND dmm$attach_file;
