?? OLDTITLE ??
?? NEWTITLE := 'bai$lrt_common_procedures', EJECT ??
?? RIGHT := 110 ??
{
{ The following procedures are common to the BAM$LRT Tape Faps.
{ The procedures assume the following global variables are defined
{ and initialized.
{
{   file_instance: ^bat$task_file_entry,
{   gfi: ^bat$global_file_information,
{   block_info: ^bat$block_info,
{   tape_descriptor: ^bat$tape_descriptor,
{   pad_blocks: boolean,
{   record_headers_exist: boolean,
{   operation: amt$fap_operation,
{   global_layer_number: amt$fap_layer_number,
{   state_info: ^file_instance^.labeled_tape_state_info (bat$labeled_tape_state_info)

?? NEWTITLE := '  close_req', EJECT ??

{ The purpose of this request is to get the tape file in consistant
{ state and close the tape file.
{ To get the tape file in a consistant state it must:
{  1) Complete writing of any partial blocks.
{  2) Tell tape block manager to align the physical and logical position.
{  3) Tell tape block manager to close the tape file.

  PROCEDURE close_req
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      error_action: bat$error_actions,
      file_position: amt$file_position,
      last_record_header_p: ^cell,
      request_status: ost$status,
      tape_failure_modes: amt$tape_failure_modes;

    status.normal := TRUE;

{ Check file position to see if any partial blocks need to be written out.
    IF bai$partial_block_exists () THEN
      bai$write_previous_block (file_identifier, status);
    IFEND;

    IF tape_descriptor^.file_label_type = amc$labeled THEN
      IF state_info^.put_op OR state_info^.eoi_labels_needed THEN
        rmp$log_debug_message ('Calling SL_PUT_END_OF_FILE_LABELS from CLOSE_REQ');
        sl_put_end_of_file_labels (file_identifier, status);
      IFEND;
    IFEND;

    error_action := bac$continue;

  /loop/
    REPEAT
      bap$tape_bm_align_position (file_identifier, tape_failure_modes, request_status);
      IF status.normal THEN
        bai$process_request_status (file_identifier, amc$close_req, request_status, tape_failure_modes,
              error_action, status);
        IF error_action = bac$exit_procedure THEN
          EXIT /loop/; {----->
        IFEND;
      IFEND;
    UNTIL error_action = bac$continue;

{ Reset record_header_fba to a relative address within the current buffer
{ if record_headers_exist = TRUE.  This must be done to ensure the correct
{ location if the tape is opened ASIS following a get_partial and close.

    IF (((block_info^.block_position = bac$middle_of_block) OR
          (gfi^.positioning_info.record_info.file_position = amc$mid_record)) AND (record_headers_exist)) THEN
      IF tape_descriptor^.get_tape_block_buffer <> NIL THEN
        last_record_header_p := #ADDRESS (#RING (tape_descriptor^.get_tape_block_buffer),
              #SEGMENT (tape_descriptor^.get_tape_block_buffer),
              gfi^.positioning_info.record_info.record_header_fba);
        IF (#OFFSET (last_record_header_p) >= #OFFSET (tape_descriptor^.get_tape_block_buffer)) THEN
          gfi^.positioning_info.record_info.record_header_fba := #OFFSET (last_record_header_p) -
                #OFFSET (tape_descriptor^.get_tape_block_buffer);
        IFEND;
      IFEND;
    IFEND;

{ This request is only needed here because concurrent opens
{ of a tape file are illegal.  If that restriction is removed,
{ this call may be required on put and get requests.

    bap$tape_bm_close (file_identifier, tape_failure_modes, request_status);

    IF status.normal THEN
      bai$process_request_status (file_identifier, amc$close_req, request_status, tape_failure_modes,
            error_action, status);
      IF error_action = bac$exit_procedure THEN
        RETURN; {----->
      IFEND;
    IFEND;

  PROCEND close_req;
?? OLDTITLE ??
?? NEWTITLE := '  close_volume_req', EJECT ??

{ The purpose of this request is to switch to the next volume of a file.

  PROCEDURE close_volume_req
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      volume_position: amt$volume_position;

    status.normal := TRUE;
    volume_position := tape_descriptor^.volume_position;

{ Attempt to flush any buffered data to tape before advance volume.

    flush_req (file_identifier, status);
    IF status.normal THEN
      IF tape_descriptor^.file_label_type = amc$labeled THEN
        sl_close_label_volume (file_identifier, status);
      ELSE { label_type <> amc$labeled  }
        bai$advance_volume (file_identifier, volume_position, status);
        tape_descriptor^.volume_position := volume_position;
      IFEND;
    IFEND;

  PROCEND close_volume_req;
?? OLDTITLE ??
?? NEWTITLE := '  erase_tape_block_req', EJECT ??

{ The purpose of this request is to erase a specified length of magnetic tape.

  PROCEDURE erase_tape_block_req
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
     VAR status: ost$status);

    VAR
      error_action: bat$error_actions,
      request_status: ost$status,
      tape_failure_modes: amt$tape_failure_modes;

    status.normal := TRUE;

  /main_program/
    BEGIN

{ Check file position to see if any partial blocks need to be written out.
      IF bai$partial_block_exists () THEN
        bai$write_previous_block (file_identifier, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;
      IFEND;

      REPEAT
        bap$tape_bm_erase_block (file_identifier, call_block.erase_tape_block.block_length,
              tape_failure_modes, request_status);
        bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
              error_action, status);
        IF error_action = bac$exit_procedure THEN
          EXIT /main_program/; {----->
        IFEND;
      UNTIL error_action = bac$continue;

    END /main_program/;
    tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
    tape_descriptor^.volume_position := amc$after_data_block;

  PROCEND erase_tape_block_req;
?? OLDTITLE ??
?? NEWTITLE := '  flush_req', EJECT ??

{ The purpose of this request is to flush any buffered data to tape.
{ This request onlyl makes sense if writing to tape.

  PROCEDURE flush_req
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      error_action: bat$error_actions,
      request_status: ost$status,
      tape_failure_modes: amt$tape_failure_modes;

    status.normal := TRUE;
    rmp$log_debug_message ('Entering FLUSH_REQ');

*if $true(bav$pad_records)
{ Pad record if compilation variable pad_records is true.

    IF bai$partial_record_exists () THEN
      rmp$log_debug_message ('Padding record');
      pad_record;
    IFEND;
*ifend

{ Check file position to see if any partial blocks need to be written out.
    IF bai$partial_block_exists () THEN
      rmp$log_debug_message ('Writing previous block');
      bai$write_previous_block (file_identifier, status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;
    IFEND;

    REPEAT
      rmp$log_debug_message ('Calling BM flush');
      bap$tape_bm_flush (file_identifier, tape_failure_modes, request_status);
      bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
            error_action, status);
      IF error_action = bac$exit_procedure THEN
        rmp$log_debug_message ('Exiting procedure');
        RETURN; {----->
      IFEND;
    UNTIL error_action = bac$continue;

  PROCEND flush_req;
?? OLDTITLE ??
?? NEWTITLE := '  get_block', EJECT ??

{
{ The purpose of this request is to call bap$tape_bm_read_next_block,
{ process the block information and request_status, and to calculate
{ the block position.
{

  PROCEDURE get_block
    (    file_identifier: amt$file_identifier;
         operation: amt$fap_operation;
         volunteered_buffer: ^bat$tape_block;
         requested_buffer_length: amt$working_storage_length;
     VAR buffer_pointer: ^bat$tape_block;
     VAR error_action: bat$error_actions;
     VAR block_position: bat$block_position;
     VAR transfer_count: amt$transfer_count;
     VAR current_volume_position: amt$volume_position;
     VAR status: ost$status);

    VAR
      block_length: amt$max_block_length,
      block_type: bat$tape_block_type,
      pre_request_volume_position: amt$volume_position,
      reissue_read_request: boolean,
      request_status: ost$status,
      tape_error_options: amt$tape_error_options,
      tape_failure_modes: amt$tape_failure_modes,
      system_media_recovery: boolean;

    status.normal := TRUE;
    pre_request_volume_position := current_volume_position;
    transfer_count := 0;

    bai$fetch_tape_error_options (tape_error_options, status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    IF pre_request_volume_position <> amc$after_data_block THEN
      block_info^.block_number := 1;
    IFEND;

    system_media_recovery := tape_error_options.perform_failure_recovery;
    error_action := bac$continue;

    REPEAT
      bap$tape_bm_read_next_block (file_identifier, operation, volunteered_buffer, requested_buffer_length,
            system_media_recovery, buffer_pointer, block_type, block_length, tape_failure_modes,
            request_status);
      IF request_status.normal OR (request_status.condition = bae$block_truncated) THEN
        tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
        status.normal := TRUE;
        IF block_type = bac$good_data_block THEN
          reissue_read_request := FALSE;
          current_volume_position := amc$after_data_block;
        ELSE
          bai$process_block_information (file_identifier, tape_descriptor^.file_label_type, operation,
                block_type, tape_error_options, tape_failure_modes, reissue_read_request,
                current_volume_position, status);
        IFEND;
        IF NOT status.normal AND (status.condition <> ame$accept_bad_block) THEN
          error_action := bac$exit_procedure;
          RETURN; {----->
        IFEND;
      ELSE
        bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
              error_action, status);
        IF error_action = bac$exit_procedure THEN
          RETURN; {----->
        IFEND;
      IFEND;
      transfer_count := block_length;
      IF (pre_request_volume_position = amc$after_data_block) AND
            (tape_descriptor^.volume_position = amc$after_data_block) THEN
        block_info^.block_number := block_info^.block_number + 1;
      IFEND;

      IF requested_buffer_length >= transfer_count THEN
        block_position := bac$beginning_of_block;
      ELSE
        block_position := bac$middle_of_block;
      IFEND;
      IF (current_volume_position = amc$after_tapemark) OR (current_volume_position = amc$eov) THEN
        transfer_count := 0;
        block_position := bac$beginning_of_block;
        reissue_read_request := FALSE;
      IFEND;
      IF NOT request_status.normal THEN
        IF request_status.condition = bae$block_truncated THEN
          block_position := bac$middle_of_block;
        IFEND;
      IFEND;

      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;
    UNTIL (error_action <> bac$retry_last_request) AND (reissue_read_request = FALSE);

  PROCEND get_block;
?? OLDTITLE ??
?? NEWTITLE := '  get_data', EJECT ??

{ The purpose of this request is to return a portion of a data block to the calling
{ routines.  It determines which part of the current block is to be returned, or
{ weather to read a new block in from tape.  This routine uses and updates information
{ stored in the block_info and tape_descriptor tables.

  PROCEDURE get_data
    (    file_identifier: amt$file_identifier;
         operation: amt$fap_operation;
         working_storage_area: ^cell;
         working_storage_length: amt$working_storage_length;
         allow_direct_io_transfer: boolean;
         start_new_block: boolean;
         convert_if_ebcdic: boolean;
     VAR status: ost$status);

    VAR
      convert_data_to_ebcdic: boolean,
      current_block_byte_address: amt$file_byte_address,
      current_block_length: amt$working_storage_length,
      error_action: bat$error_actions,
      block_position: bat$block_position,
      from_ptr: ^cell,
      os_status: ost$error,
      remaining_block_length: amt$max_block_length,
      residual_skip_count: amt$skip_count,
      request_status: ost$status,
      tape_failure_modes: amt$tape_failure_modes,
      transfer_count: amt$transfer_count,
      volume_position: amt$volume_position,
      volunteered_buffer: ^bat$tape_block,
      wsa: ^cell,
      wsl: amt$working_storage_length;

{ Initialize local variables from the global file information.
      status.normal := TRUE;
      volume_position := tape_descriptor^.volume_position;
      transfer_count := gfi^.positioning_info.record_info.transfer_count;
      block_position := block_info^.block_position;
      current_block_byte_address := block_info^.current_block_byte_address;
      current_block_length := block_info^.current_block_length;
      wsl := working_storage_length;
      wsa := working_storage_area;

      convert_data_to_ebcdic := (state_info^.character_set = amc$ebcdic) AND
            state_info^.character_conversion AND convert_if_ebcdic;

  /main_program/
    BEGIN
      IF tape_descriptor^.file_label_type = amc$labeled THEN
        IF state_info^.put_op OR state_info^.eoi_labels_needed THEN
          rmp$log_debug_message ('Calling SL_PUT_END_OF_FILE_LABELS from GET_DATA');
          sl_put_end_of_file_labels (file_identifier, status);
          rmp$log_debug_integer ('Labeled Volume Position is: ',
                $INTEGER (tape_descriptor^.labeled_volume_position));
          rmp$log_debug_integer ('Volume Position is: ', $INTEGER (tape_descriptor^.volume_position));
          rmp$log_debug_message ('Calling SL_PUT_END_OF_FILE_LABELS from CLOSE_REQ');
          IF status.normal THEN
            sl_enable_read_after_write (file_identifier, status);
          IFEND;
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;
          transfer_count := 0;
          state_info^.put_op := FALSE;
          block_position := bac$beginning_of_block;
          volume_position := amc$after_tapemark;
          EXIT /main_program/; {----->
        IFEND;

        IF bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
          transfer_count := 0;
          IF file_instance^.previous_get_at_eoi THEN
            amp$set_file_instance_abnormal (file_identifier, ame$input_after_eoi, operation, ' ', status);
          ELSE
            volume_position := amc$after_tapemark;
          IFEND;
          EXIT /main_program/; {----->
        IFEND;

      ELSE { label_type = amc$unlabeled or amc$non_standard_labeled
        IF (block_position = bac$beginning_of_block) AND (volume_position = amc$eov) THEN
          transfer_count := 0;
          IF file_instance^.previous_get_at_eoi THEN
            amp$set_file_instance_abnormal (file_identifier, ame$input_after_eoi, operation, ' ', status);
            EXIT /main_program/; {----->
          IFEND;
        IFEND;
      IFEND;

      IF start_new_block OR (block_position <> bac$middle_of_block) THEN
        current_block_byte_address := 0;
        current_block_length := 0;
        IF allow_direct_io_transfer THEN
          volunteered_buffer := wsa;
        ELSE
          volunteered_buffer := NIL;
        IFEND;

        get_block (file_identifier, operation, volunteered_buffer, wsl,
              tape_descriptor^.get_tape_block_buffer, error_action, block_position, transfer_count,
              volume_position, status);

        IF NOT status.normal AND (status.condition = ame$input_after_output) THEN
          file_instance^.previous_get_at_eoi := TRUE;
          block_position := bac$beginning_of_block;
          volume_position := amc$eov;
          status.normal := TRUE;
          EXIT /main_program/; {----->
        IFEND;

        IF (error_action = bac$exit_procedure) OR {} (volume_position = amc$eov) OR
              (volume_position = amc$after_tapemark) THEN
          EXIT /main_program/; {----->
        IFEND;
        IF wsl > transfer_count THEN
          wsl := transfer_count;
        IFEND;
        IF NOT status.normal AND (status.condition = ame$unrecovered_read_error) THEN
          EXIT /main_program/; {----->
        IFEND;

        IF volunteered_buffer = tape_descriptor^.get_tape_block_buffer THEN

{ Direct io transfer, no buffering. }
{ Clear the buffer pointer. }

          tape_descriptor^.get_tape_block_buffer := NIL;

{ Convert the data in the buffer if ebcdic.

          IF convert_data_to_ebcdic THEN
            osp$translate_bytes (volunteered_buffer, wsl, volunteered_buffer, wsl, ^osv$ebcdic_to_ascii,
                  os_status);
          IFEND;

        ELSE
          IF tape_descriptor^.get_tape_block_buffer = NIL THEN
            amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
                  'NIL get_tape_block_buffer in get_data.', status);
            EXIT /main_program/; {----->
          IFEND;
          from_ptr := tape_descriptor^.get_tape_block_buffer;
          IF convert_data_to_ebcdic THEN
            osp$translate_bytes (from_ptr, wsl, wsa, wsl, ^osv$ebcdic_to_ascii, os_status);
          ELSE
            i#move (from_ptr, wsa, wsl);
          IFEND;
        IFEND;
        current_block_byte_address := wsl;
        current_block_length := transfer_count;
        transfer_count := wsl;

      ELSE { do not start_new_block and block_position = mid_block. }
        current_block_byte_address := block_info^.current_block_byte_address;

        IF tape_descriptor^.get_tape_block_buffer <> NIL THEN
          current_block_length := block_info^.current_block_length;
          remaining_block_length := current_block_length - current_block_byte_address;

          IF wsl >= remaining_block_length THEN
            wsl := remaining_block_length;
            block_position := bac$beginning_of_block;
          ELSE
            block_position := bac$middle_of_block;
          IFEND;

          from_ptr := ^tape_descriptor^.get_tape_block_buffer^ [current_block_byte_address + 1];
          IF convert_data_to_ebcdic THEN
            osp$translate_bytes (from_ptr, wsl, wsa, wsl, ^osv$ebcdic_to_ascii, os_status);
          ELSE
            i#move (from_ptr, wsa, wsl);
          IFEND;
          current_block_byte_address := current_block_byte_address + wsl;
          transfer_count := wsl;

        ELSE { No buffer available, need to  reread the block.   }

          REPEAT
            bap$tape_bm_skip_blocks (file_identifier, amc$backward, 1, residual_skip_count,
                  tape_failure_modes, request_status);

            bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
                  error_action, status);
            IF error_action = bac$exit_procedure THEN
              EXIT /main_program/; {----->
            IFEND;
            tape_descriptor^.get_tape_block_buffer := NIL;
          UNTIL error_action = bac$continue;

{   Decrement block number to account for backspace
          IF block_info^.block_number > 1 THEN
            block_info^.block_number := block_info^.block_number - 1;
          ELSE
            tape_descriptor^.volume_position := amc$bov;
          IFEND;

          get_block (file_identifier, operation, NIL, gfi^.max_data_size,
                tape_descriptor^.get_tape_block_buffer, error_action, block_position, current_block_length,
                volume_position, status);

          IF NOT status.normal AND (status.condition = ame$input_after_output) THEN
            file_instance^.previous_get_at_eoi := TRUE;
            block_position := bac$beginning_of_block;
            volume_position := amc$eov;
            status.normal := TRUE;
            EXIT /main_program/; {----->
          IFEND;

          IF (error_action = bac$exit_procedure) OR {} (volume_position = amc$eov) OR
                (volume_position = amc$after_tapemark) THEN
            EXIT /main_program/; {----->
          IFEND;

          remaining_block_length := current_block_length - current_block_byte_address;

          IF wsl >= remaining_block_length THEN
            wsl := remaining_block_length;
            block_position := bac$beginning_of_block;
          ELSE
            block_position := bac$middle_of_block;
          IFEND;
          IF tape_descriptor^.get_tape_block_buffer = NIL THEN
            amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
                  'Get_block_buffer = NIL in get_data.', status);
            EXIT /main_program/; {----->
          IFEND;
          from_ptr := ^tape_descriptor^.get_tape_block_buffer^ [current_block_byte_address + 1];
          IF convert_data_to_ebcdic THEN
            osp$translate_bytes (from_ptr, wsl, wsa, wsl, ^osv$ebcdic_to_ascii, os_status);
          ELSE
            i#move (from_ptr, wsa, wsl);
          IFEND;
          current_block_byte_address := current_block_byte_address + wsl;
          transfer_count := wsl;
        IFEND;
      IFEND;
    END /main_program/;

{ Set fields in the file transfer descriptor.
    block_info^.block_position := block_position;
    gfi^.positioning_info.record_info.transfer_count := transfer_count;
    block_info^.current_block_length := current_block_length;
    block_info^.current_block_byte_address := current_block_byte_address;
    block_info^.residual_block_length := current_block_length - current_block_byte_address;
    tape_descriptor^.volume_position := volume_position;

  PROCEND get_data;
?? OLDTITLE ??
?? NEWTITLE := '  open_req', EJECT ??

{ The purpose of this routine is to prepare the record management portion for
{ long record tape processing.

  PROCEDURE open_req
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
         dynamic_label: ^bat$dynamic_label_attributes;
     VAR status: ost$status);

?? NEWTITLE := '    bai$open_blk_xt_hndlr', EJECT ??

    PROCEDURE bai$open_blk_xt_hndlr
      (    condition: pmt$condition;
           p_condition_info: ^pmt$condition_information;
           p_stack: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

{ The purpose of this condition handler is to handle all block
{ exit occurances that may occur while trying to open
{ a tape volume.  The assumptions is that appropriate actions
{ for the various conditions occur elsewhere.  If a block exit
{ is attempted at this level, the necessary action is to close
{ the file and get out.  Note that the tape block manager has
{ not set up any tables, thus does not need to be closed at that
{ level.

      VAR
        ignore_status: ost$status;

      condition_status.normal := TRUE;
      bap$close (file_identifier, ignore_status);

    PROCEND bai$open_blk_xt_hndlr;
?? OLDTITLE ??
?? NEWTITLE := '    initialize_tape_tables', EJECT ??

    PROCEDURE initialize_tape_tables
      (VAR status: ost$status);

{Design:
{For a labeled tape, the following attributes may be changed after labels are read:
{Block Type, Character Conversion, Character Set, Maximum Block Length, Maximum
{Record Length, Padding Character, and Record Type.
{
{For any file_label_type, the values of the 7 attributes above may be changed on each
{open via the default_creation and mandated attribute parameters of FSP$OPEN_FILE, via
{CHATLA, or via SETFA.  Block Type and Record Type are in the instance attributes.
{
{All but Block Type and Record Type are stored in LABELED_TAPE_STATE_INFO.  The values
{of the 5 attributes are initially stored here.  For a labeled tape, the 7 attributes
{defined in the HDR2 label are processed later in the OPEN process after labels are
{read.  Block Type and Record Type are updated in the instance attributes and the
{other 5 are stored in LABELED_TAPE_STATE_INFO.  This allows AMP$FETCH to return the
{correct values.

      CONST
        fw = 1;

      CONST
        ta_cc = 1,
        ta_cs = 2,
        ta_mbl = 3,
        ta_mrl = 4,
        ta_pc = 5;

      VAR
        call_block: amt$call_block,
        fetch_attribute: array [fw .. fw] of amt$fetch_item,
        file_access_options: fst$file_access_options,
        returned_attributes: fst$tla_returned_attributes,
        tape_attachments: ^array [ta_cc .. ta_pc] of fst$attachment_option;

      status.normal := TRUE;

      fetch_attribute [fw].key := amc$forced_write;

      call_block.operation := amc$fetch_req;
      call_block.fetch.file_attributes := ^fetch_attribute;
      bap$fap_control (file_identifier, call_block, global_layer_number, status);

      IF status.normal THEN
        tape_descriptor^.forced_write := fetch_attribute [fw].forced_write <> amc$unforced;

        state_info^ := bav$labeled_tape_state_info;

        PUSH tape_attachments;

        tape_attachments^ [ta_cc].selector := fsc$tape_attachment;
        tape_attachments^ [ta_cc].tape_attachment.selector := fsc$tape_character_conversion;
        tape_attachments^ [ta_cs].selector := fsc$tape_attachment;
        tape_attachments^ [ta_cs].tape_attachment.selector := fsc$tape_character_set;
        tape_attachments^ [ta_mbl].selector := fsc$tape_attachment;
        tape_attachments^ [ta_mbl].tape_attachment.selector := fsc$tape_max_block_length;
        tape_attachments^ [ta_mrl].selector := fsc$tape_attachment;
        tape_attachments^ [ta_mrl].tape_attachment.selector := fsc$tape_max_record_length;
        tape_attachments^ [ta_pc].selector := fsc$tape_attachment;
        tape_attachments^ [ta_pc].tape_attachment.selector := fsc$tape_padding_character;

        fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_next_position,
              tape_attachments^, returned_attributes, status);

        IF status.normal THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: NEXT_POSITION GETTLA status normal');
          IF fsc$tape_character_conversion IN returned_attributes THEN
            IF state_info^.character_conversion THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing TRUE for Character Conversion');
            ELSE
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing FALSE for Character Conversion');
            IFEND;
            state_info^.character_conversion := tape_attachments^ [ta_cc].tape_attachment.
                  tape_character_conversion;
          IFEND;

          IF fsc$tape_character_set IN returned_attributes THEN
            state_info^.character_set := tape_attachments^ [ta_cs].tape_attachment.tape_character_set;
            CASE state_info^.character_set OF
            = amc$ascii =
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing ASCII for Character Set');
            = amc$ebcdic =
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing EBCDIC for Character Set');
            ELSE
              rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Storing OTHER Character Set=',
                    $INTEGER (state_info^.character_set));
            CASEND;
          IFEND;

          IF fsc$tape_max_block_length IN returned_attributes THEN
            state_info^.maximum_block_length := tape_attachments^ [ta_mbl].tape_attachment.
                  tape_max_block_length;
            rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Stored MAXBL=', state_info^.maximum_block_length);
          IFEND;

          IF fsc$tape_max_record_length IN returned_attributes THEN
            state_info^.maximum_record_length := tape_attachments^ [ta_mrl].tape_attachment.
                  tape_max_record_length;
            rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Stored MAXRL=', state_info^.maximum_record_length);
          IFEND;

          IF fsc$tape_padding_character IN returned_attributes THEN
            state_info^.padding_character := tape_attachments^ [ta_pc].tape_attachment.tape_padding_character;
          IFEND;

          gfi^.max_data_size := state_info^.maximum_block_length;
          gfi^.max_block_size := state_info^.maximum_block_length;
          gfi^.max_record_length := state_info^.maximum_record_length;
          gfi^.padding_character := state_info^.padding_character;

          IF file_instance^.instance_attributes.static_label.block_type = amc$system_specified THEN
            IF (tape_descriptor^.file_label_type = amc$labeled) OR
                  (($pft$usage_selections [pfc$shorten, pfc$append] * dynamic_label^.access_mode) <>
                  ($pft$usage_selections [])) THEN
              rmp$log_debug_integer ('LABELED_TAPE_DEBUG: REQUESTED_DENSITY=',
                    $INTEGER (tape_descriptor^.requested_density));
              IF tape_descriptor^.requested_density = rmc$38000 THEN
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting GFI max block size to 32640');
                gfi^.max_data_size := 32640;
                gfi^.max_block_size := 32640;
                state_info^.maximum_block_length := 32640;
              ELSE
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting GFI max block size to 4128');
                gfi^.max_data_size := 4128;
                gfi^.max_block_size := 4128;
                state_info^.maximum_block_length := 4128;
              IFEND;
            IFEND;
          IFEND;

          IF tape_descriptor^.file_label_type = amc$labeled THEN
            CASE dynamic_label^.open_position OF
            = amc$open_at_bop, amc$open_no_positioning =
              amp$set_file_instance_abnormal (file_identifier, ame$improper_open_position,
                    call_block.operation, '', status);
              RETURN; {----->
            ELSE
            CASEND;
            #UNCHECKED_CONVERSION (dynamic_label^.access_mode, file_access_options);
            sl_store_authorized_access (file_access_options, status);
          IFEND;
        IFEND;
      IFEND;

    PROCEND initialize_tape_tables;
?? OLDTITLE ??
?? EJECT ??

    VAR
      block_position: bat$block_position,
      current_block_length: amt$working_storage_length,
      error_action: bat$error_actions,
      file_position: amt$file_position,
      os_status: ost$error,
      request_status: ost$status,
      residual_skip_count: amt$skip_count,
      temp_call_block: amt$call_block,
      tape_failure_modes: amt$tape_failure_modes;

  /main_program/
    BEGIN

      status.normal := TRUE;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering OPEN_REQ');

      initialize_tape_tables (status);
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

{ Initiate the tape block manager for this file.
      REPEAT
        osp$establish_block_exit_hndlr (^bai$open_blk_xt_hndlr);
        IF tape_descriptor^.tape_attachment_information.volume_initialization THEN
          sl_setup_volume_initialization (status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;
        IFEND;

        IF (tape_descriptor^.volume_number = 1) AND (tape_descriptor^.volume_position = amc$bov) AND
              (tape_descriptor^.initial_volume.initial_read_labels_attempt) THEN
          CASE tape_descriptor^.file_label_type OF
          = amc$unlabeled, amc$non_standard_labeled =
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_PREAUTHORIZE_ACCESS_METHOD - unlabeled');
            sl_preauthorize_access_method (file_identifier, tape_descriptor^.file_label_type, status);
          ELSE
          CASEND;
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;
        IFEND;

        bap$tape_bm_open (file_identifier, gfi^.max_data_size, request_status);
        osp$disestablish_cond_handler;
        tape_failure_modes := $amt$tape_failure_modes [];
        bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
              error_action, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;
      UNTIL error_action <> bac$retry_last_request;

      CASE tape_descriptor^.file_label_type OF

      = amc$unlabeled =
        IF (tape_descriptor^.volume_number = 1) AND (tape_descriptor^.volume_position = amc$bov) AND
              (tape_descriptor^.initial_volume.initial_read_labels_attempt) THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_AUTHORIZE_ACCESS_METHOD - unlabeled');
          sl_authorize_access_method (file_identifier, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;
        IFEND;
        CASE dynamic_label^.open_position OF
        = amc$open_no_positioning =

          IF (block_info^.block_position = bac$middle_of_block) OR
                ((gfi^.positioning_info.record_info.file_position = amc$mid_record) AND
                (record_headers_exist)) THEN

{   Re-read the last block such that logical position is maintained
            REPEAT
              bap$tape_bm_skip_blocks (file_identifier, amc$backward, 1, residual_skip_count,
                    tape_failure_modes, request_status);

              bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
                    error_action, status);
              IF error_action = bac$exit_procedure THEN
                EXIT /main_program/; {----->
              IFEND;
              tape_descriptor^.get_tape_block_buffer := NIL;

            UNTIL error_action = bac$continue;

{   Decrement block number to account for backspace
            IF block_info^.block_number > 1 THEN
              block_info^.block_number := block_info^.block_number - 1;
            ELSE
              tape_descriptor^.volume_position := amc$bov;
            IFEND;

            get_block (file_identifier, operation, NIL, gfi^.max_data_size,
                  tape_descriptor^.get_tape_block_buffer, error_action, block_position, current_block_length,
                  tape_descriptor^.volume_position, status);

            IF (error_action = bac$exit_procedure) OR NOT status.normal THEN
              EXIT /main_program/; {----->
            IFEND;

{   Reset record_header_fba to byte offset relative to segment.
            IF record_headers_exist AND (tape_descriptor^.get_tape_block_buffer <> NIL) THEN
              gfi^.positioning_info.record_info.record_header_fba :=
                    #OFFSET (tape_descriptor^.get_tape_block_buffer) +
                    gfi^.positioning_info.record_info.record_header_fba;
            IFEND;
          ELSE
            tape_descriptor^.get_tape_block_buffer := NIL;
            tape_descriptor^.put_tape_block_buffer := NIL;
            tape_descriptor^.last_data_operation := amc$open_req;
          IFEND;

        = amc$open_at_eoi =
          temp_call_block.operation := amc$skip_req;
          temp_call_block.skp.unit := amc$skip_tape_mark {amc$skip_block} ;
          temp_call_block.skp.count := 1;
          temp_call_block.skp.direction := amc$forward;
          temp_call_block.skp.file_position := ^file_position;
          skip_req (file_identifier, temp_call_block, status);
          IF NOT status.normal AND (status.condition = ame$skip_encountered_eoi) THEN
            status.normal := TRUE;
            file_instance^.residual_skip_count := 0;
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Unlabeled - Setting AT_EOI to TRUE');
            tape_descriptor^.at_eoi := TRUE;
          IFEND;
          tape_descriptor^.last_data_operation := amc$open_req;

        = amc$open_at_boi =
          rewind_tape (file_identifier, status);
          IF NOT status.normal THEN
            EXIT /main_program/; {----->
          IFEND;
          tape_descriptor^.last_data_operation := amc$open_req;

        ELSE
          amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
                'Unknown open_position in open_req (lrt fap)', status);
        CASEND;

      = amc$labeled =
        sl_open_label_file (file_identifier, call_block, layer_number, file_instance^.local_file_name,
              status);
        tape_descriptor^.rewind_file_command := FALSE;
        tape_descriptor^.get_tape_block_buffer := NIL;
        tape_descriptor^.put_tape_block_buffer := NIL;
        tape_descriptor^.last_data_operation := amc$open_req;

      = amc$non_standard_labeled =
        IF (tape_descriptor^.volume_number = 1) AND (tape_descriptor^.volume_position = amc$bov) AND
              (tape_descriptor^.initial_volume.initial_read_labels_attempt) THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_AUTHORIZE_ACCESS_METHOD - non standard');
          sl_authorize_access_method (file_identifier, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;
        IFEND;

{ Always open ASIS.
        tape_descriptor^.get_tape_block_buffer := NIL;
        tape_descriptor^.put_tape_block_buffer := NIL;
        tape_descriptor^.last_data_operation := amc$open_req;
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
              'Unknown file_label_type in open_req (lrt fap)', status);
      CASEND;

      state_info^.translated_record_padding_char := state_info^.padding_character;
      IF (state_info^.character_set = amc$ebcdic) AND (state_info^.character_conversion = TRUE) THEN
        osp$translate_bytes (^state_info^.translated_block_padding_char, 1,
              ^state_info^.translated_block_padding_char, 1, ^osv$ascii_to_ebcdic, os_status);
        osp$translate_bytes (^state_info^.translated_record_padding_char, 1,
              ^state_info^.translated_record_padding_char, 1, ^osv$ascii_to_ebcdic, os_status);
      IFEND;
    END /main_program/;

    IF NOT status.normal THEN
      bap$tape_bm_close (file_identifier, tape_failure_modes, request_status);
      bap$close (file_identifier, request_status);
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting OPEN_REQ');

  PROCEND open_req;
?? OLDTITLE ??
?? NEWTITLE := '  put_data', EJECT ??

  PROCEDURE put_data
    (    file_identifier: amt$file_identifier;
         operation: amt$fap_operation;
         working_storage_area: ^cell;
         working_storage_length: amt$working_storage_length;
         term_option: amt$term_option;
         terminate_previous_record: boolean;
         convert_if_ebcdic: boolean;
     VAR status: ost$status);

    VAR
      buffer_ptr: ^bat$tape_block,
      convert_data_to_ebcdic: boolean,
      current_block_byte_address: amt$file_byte_address,
      current_block_length: amt$working_storage_length,
      data_already_moved: boolean,
      error_action: bat$error_actions,
      block_position: bat$block_position,
      force_immediate_write: boolean,
      i: integer,
      os_status: ost$error,
      padding_character: amt$padding_character,
      request_status: ost$status,
      residual_block_length: 0 .. amc$maximum_block - 1,
      system_media_recovery: boolean,
      tape_error_options: amt$tape_error_options,
      tape_failure_modes: amt$tape_failure_modes,
      temp_wsa: ^array [1 .. amc$maximum_block - 1] of char,
      wsa: ^cell,
      wsl: amt$working_storage_length;

      status.normal := TRUE;
      block_position := block_info^.block_position;
      wsa := working_storage_area;
      wsl := working_storage_length;
      current_block_length := block_info^.current_block_length;
      current_block_byte_address := block_info^.current_block_byte_address;
      padding_character := state_info^.translated_block_padding_char;
      convert_data_to_ebcdic := (state_info^.character_set = amc$ebcdic) AND
            state_info^.character_conversion AND convert_if_ebcdic;
      data_already_moved := FALSE;

  /main_program/
    BEGIN

{ Fetch the tape error options.
      bai$fetch_tape_error_options (tape_error_options, status);
      IF NOT status.normal THEN
        EXIT /main_program/; {----->
      IFEND;

      system_media_recovery := tape_error_options.perform_failure_recovery;

{ Set forced write attribute.
      force_immediate_write := tape_descriptor^.forced_write;

      IF tape_descriptor^.volume_position <> amc$after_data_block THEN
        block_info^.block_number := 1;
      IFEND;

      IF terminate_previous_record THEN
        IF bai$partial_block_exists () THEN

{ Write previous record.
          IF pad_blocks AND (current_block_length < gfi^.min_block_length) THEN
            temp_wsa := ^tape_descriptor^.put_tape_block_buffer^ [current_block_byte_address + 1];
            i#fill (padding_character, ^temp_wsa^, gfi^.min_block_length - current_block_length);
            current_block_length := gfi^.min_block_length;
            current_block_byte_address := gfi^.min_block_length;
          IFEND;

          REPEAT
            bap$tape_bm_write_next_block (file_identifier, tape_descriptor^.put_tape_block_buffer,
                  current_block_length, system_media_recovery, force_immediate_write, tape_failure_modes,
                  request_status);

            bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
                  error_action, status);
            IF error_action = bac$exit_procedure THEN
              EXIT /main_program/; {----->
            IFEND;
          UNTIL error_action <> bac$retry_last_request;
          tape_descriptor^.put_tape_block_buffer := NIL;
          IF tape_descriptor^.volume_position = amc$after_data_block THEN
            block_info^.block_number := block_info^.block_number + 1;
          IFEND;
          tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
          tape_descriptor^.volume_position := amc$after_data_block;
        IFEND;
        block_position := bac$beginning_of_block;
        current_block_byte_address := 0;
        current_block_length := 0;

{ A zero length transfer will close out the current record, while
{ transfering no data.
        IF wsl = 0 THEN
          block_position := bac$beginning_of_block;
          EXIT /main_program/; {----->
        IFEND;
      IFEND;
      residual_block_length := gfi^.max_data_size - current_block_byte_address;

{ Check if possible direct IO. If so and the data is to be converted, a buffer must be
{ reserved and the data converted from the user buffer to the block manager buffer.

      IF ((convert_data_to_ebcdic) AND (block_position <> bac$middle_of_block) AND
            (term_option = amc$terminate)) THEN

        IF wsl > residual_block_length THEN
          amp$set_file_instance_abnormal (file_identifier, ame$record_exceeds_mbl, operation, ' ', status);
          EXIT /main_program/; {----->
        IFEND;

        REPEAT
          bap$tape_bm_reserve_blk_buffer (file_identifier, tape_descriptor^.put_tape_block_buffer,
                tape_failure_modes, request_status);
          bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
                error_action, status);
          IF error_action = bac$exit_procedure THEN
            EXIT /main_program/; {----->
          IFEND;
        UNTIL error_action <> bac$retry_last_request;

        osp$translate_bytes (wsa, wsl, tape_descriptor^.put_tape_block_buffer, wsl, ^osv$ascii_to_ebcdic,
              os_status);
        block_position := bac$middle_of_block;
        current_block_length := wsl;
        current_block_byte_address := wsl;
        data_already_moved := TRUE;
      IFEND;

      CASE term_option OF
      = amc$start =

        IF block_position = bac$middle_of_block THEN
          IF NOT terminate_previous_record THEN
            amp$set_file_instance_abnormal (file_identifier, 0, operation,
                  'lrt fap: illegal combination of f' CAT 'ile_postion = mid_record, terminate_previous_r' CAT
                  'ecord = FALSE, and term_option = start', status);
            RETURN; {----->
          IFEND;
        IFEND;
        residual_block_length := gfi^.max_data_size;
        IF wsl > residual_block_length THEN
          amp$set_file_instance_abnormal (file_identifier, ame$record_exceeds_mbl, operation, ' ', status);
          EXIT /main_program/; {----->
        IFEND;

        REPEAT
          bap$tape_bm_reserve_blk_buffer (file_identifier, tape_descriptor^.put_tape_block_buffer,
                tape_failure_modes, request_status);
          bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
                error_action, status);
          IF error_action = bac$exit_procedure THEN
            EXIT /main_program/; {----->
          IFEND;
        UNTIL error_action <> bac$retry_last_request;

        IF convert_data_to_ebcdic THEN
          osp$translate_bytes (wsa, wsl, tape_descriptor^.put_tape_block_buffer, wsl, ^osv$ascii_to_ebcdic,
                os_status);
        ELSE
          i#move (wsa, tape_descriptor^.put_tape_block_buffer, wsl);
        IFEND;
        block_position := bac$middle_of_block;
        current_block_length := wsl;
        current_block_byte_address := wsl;

      = amc$continue =

        IF block_position <> bac$middle_of_block THEN
          amp$set_file_instance_abnormal (file_identifier, ame$improper_continue, operation, ' ', status);
          EXIT /main_program/; {----->
        IFEND;
        IF tape_descriptor^.put_tape_block_buffer = NIL THEN
          amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
                'Put block buffer = NIL in put_data', status);
          EXIT /main_program/; {----->
        IFEND;

        IF wsl > residual_block_length THEN
          amp$set_file_instance_abnormal (file_identifier, ame$record_exceeds_mbl, operation, ' ', status);
          EXIT /main_program/; {----->
        IFEND;

        buffer_ptr := ^tape_descriptor^.put_tape_block_buffer^ [current_block_byte_address + 1];
        IF convert_data_to_ebcdic THEN
          osp$translate_bytes (wsa, wsl, buffer_ptr, wsl, ^osv$ascii_to_ebcdic, os_status);
        ELSE
          i#move (wsa, buffer_ptr, wsl);
        IFEND;

        current_block_length := current_block_length + wsl;
        current_block_byte_address := current_block_byte_address + wsl;

      = amc$terminate =

        IF wsl > residual_block_length THEN
          amp$set_file_instance_abnormal (file_identifier, ame$record_exceeds_mbl, operation, ' ', status);
          EXIT /main_program/; {----->
        IFEND;

        IF block_position = bac$middle_of_block THEN
          IF tape_descriptor^.put_tape_block_buffer <> NIL THEN
            IF NOT data_already_moved THEN
              buffer_ptr := ^tape_descriptor^.put_tape_block_buffer^ [current_block_byte_address + 1];
              IF convert_data_to_ebcdic THEN
                osp$translate_bytes (wsa, wsl, buffer_ptr, wsl, ^osv$ascii_to_ebcdic, os_status);
              ELSE
                i#move (wsa, buffer_ptr, wsl);
              IFEND;
              current_block_length := current_block_length + wsl;
            IFEND;

            IF pad_blocks AND (current_block_length < gfi^.min_block_length) THEN
              temp_wsa := ^tape_descriptor^.put_tape_block_buffer^ [current_block_byte_address + wsl + 1];
              i#fill (padding_character, ^temp_wsa^, gfi^.min_block_length - current_block_length);
              current_block_length := gfi^.min_block_length;
              current_block_byte_address := gfi^.min_block_length;
            IFEND;

            REPEAT
              bap$tape_bm_write_next_block (file_identifier, tape_descriptor^.put_tape_block_buffer,
                    current_block_length, system_media_recovery, force_immediate_write, tape_failure_modes,
                    request_status);
              bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
                    error_action, status);
              IF error_action = bac$exit_procedure THEN
                IF NOT status.normal AND (status.condition = ame$end_of_tape_op_inhibited) THEN
                  current_block_length := block_info^.current_block_length;
                  current_block_byte_address := block_info^.current_block_byte_address;
                IFEND;
                EXIT /main_program/; {----->
              IFEND;
            UNTIL error_action <> bac$retry_last_request;
            IF tape_descriptor^.volume_position = amc$after_data_block THEN
              block_info^.block_number := block_info^.block_number + 1;
            IFEND;
            tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
            tape_descriptor^.volume_position := amc$after_data_block;
            tape_descriptor^.put_tape_block_buffer := NIL;
            block_position := bac$beginning_of_block;
            current_block_byte_address := 0;
            current_block_length := 0;
          ELSE
            amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
                  'Put block buffer = NIL and block_position = bac$middle_of_block in put_data.', status);
          IFEND;
        ELSE

          REPEAT
            bap$tape_bm_write_next_block (file_identifier, wsa, wsl, system_media_recovery,
                  force_immediate_write, tape_failure_modes, request_status);
            bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
                  error_action, status);
            IF error_action = bac$exit_procedure THEN
              EXIT /main_program/; {----->
            IFEND;
          UNTIL error_action <> bac$retry_last_request;
          IF tape_descriptor^.volume_position = amc$after_data_block THEN
            block_info^.block_number := block_info^.block_number + 1;
          IFEND;
          tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
          tape_descriptor^.volume_position := amc$after_data_block;
          tape_descriptor^.put_tape_block_buffer := NIL;
          block_position := bac$beginning_of_block;
          current_block_byte_address := 0;
          current_block_length := 0;
        IFEND;
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
              'Improper term_option in put_data.', status);
      CASEND;

    END /main_program/;

    block_info^.block_position := block_position;
    block_info^.current_block_length := current_block_length;
    block_info^.current_block_byte_address := current_block_byte_address;
    block_info^.residual_block_length := gfi^.max_data_size - current_block_byte_address;

  PROCEND put_data;
?? OLDTITLE ??
?? NEWTITLE := '  rewind_req', EJECT ??

{
{ The purpose of this request is to rewind a tape file to the beginning
{ of information.  The tape rewind interface is called to invoke the
{ physical repositioning of the tape.
{

  PROCEDURE rewind_req
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
     VAR status: ost$status);

    VAR
      error_action: bat$error_actions,
      request_status: ost$status,
      file_position: amt$file_position,
      tape_failure_modes: amt$tape_failure_modes;

    status.normal := TRUE;

{ Check file position to see if any partial blocks need to be written out.
      IF bai$partial_block_exists () THEN
        bai$write_previous_block (file_identifier, status);
        IF NOT status.normal THEN
          return;
        IFEND;
      IFEND;

      IF tape_descriptor^.file_label_type = amc$labeled THEN
        sl_rewind_ansi_file (file_identifier, status);
        IF NOT status.normal THEN
          return;
        IFEND;
      ELSE
        rewind_tape (file_identifier, status);
        IF NOT status.normal THEN
          return;
        IFEND;
      IFEND;

  PROCEND rewind_req;
?? OLDTITLE ??
?? NEWTITLE := '  rewind_tape', EJECT ??

  PROCEDURE rewind_tape
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      error_action: bat$error_actions,
      request_status: ost$status,
      tape_failure_modes: amt$tape_failure_modes;

    status.normal := TRUE;

    REPEAT
      bap$tape_bm_rewind (file_identifier, tape_failure_modes, request_status);
      bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
            error_action, status);
      IF error_action = bac$exit_procedure THEN
        RETURN; {----->
      IFEND;
    UNTIL error_action <> bac$retry_last_request;

    bai$init_boi_tape_position;

  PROCEND rewind_tape;
?? OLDTITLE ??
?? NEWTITLE := '  switch_from_read_to_write', EJECT ??

  PROCEDURE switch_from_read_to_write
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      error_action: bat$error_actions,
      request_status: ost$status,
      tape_failure_modes: amt$tape_failure_modes;

    status.normal := TRUE;

    bap$tape_bm_read_to_write (file_identifier, tape_descriptor^.get_tape_block_buffer,
          tape_descriptor^.put_tape_block_buffer, tape_failure_modes, request_status);
    bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes, error_action,
          status);
    IF NOT status.normal THEN
      RETURN; {----->
    IFEND;

    IF tape_descriptor^.put_tape_block_buffer <> NIL THEN
      block_info^.residual_block_length := gfi^.max_data_size - block_info^.current_block_byte_address;
      block_info^.current_block_length := block_info^.current_block_byte_address;
      IF block_info^.block_number > 1 THEN
        block_info^.block_number := block_info^.block_number - 1;
      ELSE
        tape_descriptor^.volume_position := amc$bov;
      IFEND;
    ELSE {previous read buffer had unrecovered error data in it}
      block_info^.block_position := bac$beginning_of_block;
    IFEND;

    tape_descriptor^.get_tape_block_buffer := NIL;

  PROCEND switch_from_read_to_write;
?? OLDTITLE ??
?? NEWTITLE := '  validate_skip_parameters', EJECT ??

  PROCEDURE validate_skip_parameters
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         skip_partitions_valid: boolean;
         skip_partitions_back_valid: boolean;
         skip_records_valid: boolean;
         skip_records_back_valid: boolean;
     VAR status: ost$status);

    status.normal := TRUE;
    call_block.skp.file_position^ := gfi^.positioning_info.record_info.file_position;

    IF (call_block.skp.count < 0) OR (call_block.skp.count > UPPERVALUE (amt$skip_count)) THEN
      amp$set_file_instance_abnormal (file_identifier, ame$improper_skip_count, operation, '', status);
      RETURN; {----->
    IFEND;

    file_instance^.residual_skip_count := call_block.skp.count;

    CASE call_block.skp.unit OF
    = amc$skip_partition =
      IF NOT skip_partitions_valid THEN
        amp$set_file_instance_abnormal (file_identifier, ame$unsupported_skip, operation, 'PARTITIONS',
              status);
        RETURN; {----->
      IFEND;

      CASE call_block.skp.direction OF
      = amc$forward =
        ;
      = amc$backward =
        IF NOT skip_partitions_back_valid THEN
          amp$set_file_instance_abnormal (file_identifier, ame$unsupported_skip, operation,
                'BACKWARD PARTITIONS', status);
          RETURN; {----->
        IFEND;
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$improper_skip_direction, operation, 'PARTITIONS',
              status);
        RETURN; {----->
      CASEND;

    = amc$skip_record =
      IF NOT skip_records_valid THEN
        amp$set_file_instance_abnormal (file_identifier, ame$unsupported_skip, operation, 'RECORDS', status);
        RETURN; {----->
      IFEND;

      CASE call_block.skp.direction OF
      = amc$forward =
        ;
      = amc$backward =
        IF NOT skip_records_back_valid THEN
          amp$set_file_instance_abnormal (file_identifier, ame$unsupported_skip, operation,
                'BACKWARD RECORDS', status);
          RETURN; {----->
        IFEND;
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$improper_skip_direction, operation, 'RECORDS',
              status);
        RETURN; {----->
      CASEND;

    = amc$skip_tape_mark =
      IF tape_descriptor^.file_label_type = amc$labeled THEN
        amp$set_file_instance_abnormal (file_identifier, ame$improper_labelled_skip_unit, operation, '',
              status);
        RETURN; {----->
      IFEND;

      CASE call_block.skp.direction OF
      = amc$forward, amc$backward =
        ;
      ELSE
        amp$set_file_instance_abnormal (file_identifier, ame$improper_skip_direction, operation, 'TAPEMARKS',
              status);
        RETURN; {----->
      CASEND;

    ELSE
      amp$set_file_instance_abnormal (file_identifier, ame$improper_skip_unit, operation, '', status);
      RETURN; {----->
    CASEND;

    IF tape_descriptor^.file_label_type = amc$labeled THEN
      IF call_block.skp.direction = amc$backward THEN
        IF state_info^.put_op OR state_info^.eoi_labels_needed THEN
          rmp$log_debug_message ('Calling SL_PUT_END_OF_FILE_LABELS from VALIDATE_SKIP_PARAMETERS');
          sl_put_end_of_file_labels (file_identifier, status);
          IF status.normal THEN
            sl_enable_read_after_write (file_identifier, status);
          IFEND;
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;
        IFEND;
        IF bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
          {   HDR1 HDR2* data * EOF1 EOF2* * *
          {                               ^
          sl_advance_tapemark (file_identifier, amc$backward, 2, status);
          {   HDR1 HDR2* data * EOF1 EOF2* * *
          {                  ^
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;
        IFEND;
        state_info^.put_op := FALSE;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to within ansi file - skipb');
        tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
        file_instance^.previous_get_at_eoi := FALSE;

      ELSE { direction = forward  }

        IF state_info^.put_op OR state_info^.eoi_labels_needed THEN
          rmp$log_debug_message ('Calling SL_PUT_END_OF_FILE_LABELS from VALIDATE_SKIP_PARAMETERS');
          sl_put_end_of_file_labels (file_identifier, status);
          IF status.normal THEN
            sl_enable_read_after_write (file_identifier, status);
          IFEND;
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;
          state_info^.put_op := FALSE;
        IFEND;

        IF bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
          call_block.skp.file_position^ := amc$eoi;
          gfi^.positioning_info.record_info.file_position := amc$eoi;
          gfi^.positioning_info.record_info.record_length := 0;
          gfi^.positioning_info.record_info.residual_record_length := 0;
          gfi^.positioning_info.record_info.transfer_count := 0;
          IF call_block.skp.count = 0 THEN
            RETURN; {----->
          IFEND;
          IF call_block.skp.unit = amc$skip_record THEN
            amp$set_file_instance_abnormal (file_identifier, ame$skip_encountered_eoi, operation, 'RECORDS',
                  status);
          ELSE { call_block.skp.unit = amc$skip_partition
            amp$set_file_instance_abnormal (file_identifier, ame$skip_encountered_eoi, operation,
                  'PARTITIONS', status);
          IFEND;
          RETURN; {----->
        IFEND;
      IFEND;
    IFEND;

  PROCEND validate_skip_parameters;
?? OLDTITLE ??
?? NEWTITLE := '  write_tape_mark_req', EJECT ??

  PROCEDURE write_tape_mark_req
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
     VAR status: ost$status);

    VAR
      error_action: bat$error_actions,
      force_immediate_write: boolean,
      request_status: ost$status,
      system_media_recovery: boolean,
      tape_error_options: amt$tape_error_options,
      tape_failure_modes: amt$tape_failure_modes;

  /main_program/
    BEGIN
      status.normal := TRUE;
      bai$fetch_tape_error_options (tape_error_options, status);
      IF NOT status.normal THEN
        EXIT /main_program/; {----->
      IFEND;
      system_media_recovery := tape_error_options.perform_failure_recovery;

      force_immediate_write := tape_descriptor^.forced_write;

{ Check file position to see if any partial blocks need to be written out.
      IF bai$partial_block_exists () THEN
        bai$write_previous_block (file_identifier, status);
        IF NOT status.normal THEN
          EXIT /main_program/; {----->
        IFEND;
      IFEND;

      REPEAT
        bap$tape_bm_write_tapemark (file_identifier, system_media_recovery, force_immediate_write,
              tape_failure_modes, request_status);

        bai$process_request_status (file_identifier, operation, request_status, tape_failure_modes,
              error_action, status);
        IF error_action = bac$exit_procedure THEN
          EXIT /main_program/; {----->
        IFEND;

        CASE tape_descriptor^.file_label_type OF
        = amc$unlabeled =
          IF NOT request_status.normal AND (request_status.condition = bae$vol_end_operation_completed) THEN

{ Curious situation for unlabeled tapes.
{
{   Have just completed writing the tapemark, however some requests will force
{   an advance volume request.  This will write two more tapemarks before
{   advancing, leaving three tapemarks at the end of the current volume.
{   When reading, the first two tapemarks will be interpreted as end of volume,
{   and the third tapemark will be lost.  Therefore, the write tapemark request
{   needs to be reissued.

            error_action := bac$retry_last_request;
          IFEND;

        = amc$labeled, amc$non_standard_labeled =

{ To be determined.
        ELSE
          amp$set_file_instance_abnormal (file_identifier, ame$tape_rcd_mgr_malfunction, operation,
                'Unknown label_type in write_tape_mark_req.', status);
        CASEND;
      UNTIL error_action <> bac$retry_last_request;
    END /main_program/;

    tape_descriptor^.volume_position := amc$after_tapemark;

  PROCEND write_tape_mark_req;
?? OLDTITLE ??
?? EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ame$label_validation_errors
*copyc fsd$ansi_label_identifiers
*copyc fst$ansi_eof1_label
*copyc fst$ansi_eof2_label
*copyc fst$ansi_eov1_label
*copyc fst$ansi_eov2_label
*copyc fst$ansi_hdr1_label
*copyc fst$ansi_hdr2_label
*copyc fst$ansi_vol1_label
*copyc fst$tape_security_call_block
?? POP ??
*copyc amp$access_method
*copyc amp$set_local_name_abnormal
*copyc avp$removable_media_admin
*copyc bap$after_trailer_labels
*copyc bap$change_tape_bt_and_rt
*copyc bap$free_tape_label_sequences
*copyc bap$get_phn_via_file_id
*copyc bap$get_tape_security_state
*copyc bap$next_position_is_bos
*copyc bap$store_unsecured_tape_labels
*copyc bap$tape_bm_write_label_mark
*copyc bav$labeled_tape_state_info
*copyc clp$convert_integer_to_rjstring
*copyc clp$convert_string_to_integer
*copyc clp$get_fs_path_elements
*copyc cmp$get_logical_unit_number_r3
*copyc dmp$setup_tape_init_in_progress
*copyc dmp$validate_tape_element
*copyc fsp$get_tape_label_attributes
*copyc fsp$locate_tape_label
*copyc fsp$path_element
*copyc fsp$file_header_labels
*copyc fsp$file_trailer_labels
*copyc fsp$header_labels
*copyc fsp$trailer_labels
*copyc fsp$ve_wrote_ansi_file
*copyc fsp$version_one_tape_label
*copyc fsp$volume_header_labels
*copyc fsp$volume_trailer_labels
*copyc i#fill
*copyc i#move
*copyc osp$append_status_file
*copyc osp$append_status_parameter
*copyc osp$generate_error_message
*copyc osp$generate_log_message
*copyc osp$set_status_condition
*copyc osp$translate_bytes
*copyc oss$task_private
*copyc osv$task_private_heap
*copyc pmp$get_date
*copyc rmp$classify_tape_volume
*copyc rmp$format_vol_classification
*copyc rmp$log_debug_integer
*copyc rmp$log_debug_message
*copyc rmp$log_debug_status
*copyc rmv$tape_debug_mode

  VAR
    bov_position: boolean;

  TYPE
    tape_attach_info_sources = set of fst$tape_attach_info_source;

  VAR
    tape_label_sources: [STATIC, READ, oss$job_paged_literal] tape_attach_info_sources :=
          [fsc$tape_label_attr_command, fsc$tape_open_tape_attachment, fsc$tape_hdr1_label,
          fsc$tape_hdr2_label];

?? NEWTITLE := '    sl_adjust_trailer_labels', EJECT ??

  PROCEDURE sl_adjust_trailer_labels
    (    file_identifier: amt$file_identifier;
         label_sequence: ^SEQ ( * );
         new_label_identifier: fst$ansi_label_identifier;
     VAR status: ost$status);

{Design: FSP$GET_TAPE_LABEL_ATTRIBUTES is used to build the trailer labels for the
{next position.  It always builds file trailer labels, i.e. * EOF1 EOF2 *.  The
{block_count in the EOF1 label is zero.  By ANSI standard, the EOF1 and EOV1 labels
{are identical as are the EOF2 and EOV2 labels.  This procedure stores the proper
{label identifier (EOF or EOV) for the label group we are writing and sets the block
{count to the physical block count for the current file or file section on the
{current volume.

    CONST
      write_mode = 'WRITTEN';

    VAR
      block_count: integer,
      buffered_blocks: bat$tape_block_buffer_count,
      eox1_label: ^fst$ansi_eof1_label,
      eox2_label: ^fst$ansi_eof2_label,
      label_identifier: fst$tape_label_identifier,
      label_locator: fst$tape_label_locator,
      trailer_labels: ^SEQ ( * );

    status.normal := TRUE;

    bap$tape_bm_unwritten_blk_count (file_identifier, buffered_blocks, status);
    IF status.normal THEN
      state_info^.buffered_blocks := buffered_blocks;
      IF state_info^.put_op THEN
        block_count := gfi^.positioning_info.block_info.block_number - state_info^.buffered_blocks;
      ELSE
        block_count := 0;
      IFEND;

      IF new_label_identifier = fsc$ansi_eof_label_identifier THEN
        sl_log_eof_block_count (block_count, write_mode);
      ELSE
        sl_log_eov_block_count (block_count, write_mode);
      IFEND;

      trailer_labels := label_sequence;
      RESET trailer_labels;
      label_identifier.location_method := fsc$tape_label_locate_by_kind;
      label_identifier.label_kind := fsc$ansi_eof1_label_kind;
      fsp$locate_tape_label (trailer_labels, label_identifier, label_locator);

      IF label_locator.label_found THEN
        RESET label_locator.label_block;
        NEXT eox1_label IN label_locator.label_block;
        eox1_label^.label_identifier := new_label_identifier;
        clp$convert_integer_to_rjstring (block_count, 10, FALSE, '0', eox1_label^.block_count, status);
        IF status.normal THEN
          label_identifier.location_method := fsc$tape_label_locate_by_kind;
          label_identifier.label_kind := fsc$ansi_eof2_label_kind;
          fsp$locate_tape_label (trailer_labels, label_identifier, label_locator);

          IF label_locator.label_found THEN
            RESET label_locator.label_block;
            NEXT eox2_label IN label_locator.label_block;
            eox2_label^.label_identifier := new_label_identifier;
          ELSE
            osp$set_status_condition (ame$label_not_in_sequence, status);
            osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
            osp$append_status_parameter (osc$status_parameter_delimiter, fsc$ansi_eof_label_identifier,
                  status);
          IFEND;
        IFEND;
      ELSE
        osp$set_status_condition (ame$label_not_in_sequence, status);
        osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, fsc$ansi_eof_label_identifier, status);
      IFEND;
    IFEND;
  PROCEND sl_adjust_trailer_labels;

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

  PROCEDURE sl_advance_tapemark
    (    file_identifier: amt$file_identifier;
         direction: amt$skip_direction;
         count: amt$skip_count;
     VAR status: ost$status);

    VAR
      skip_call_block: amt$call_block;

    status.normal := TRUE;

    IF direction = amc$forward THEN
      rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Skipping forward tapemarks: ', count);
    ELSE
      rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Skipping backward tapemarks: ', count);
    IFEND;
    skip_call_block.operation := amc$skip_req;
    skip_call_block.skp.direction := direction;
    skip_call_block.skp.count := count;
    skip_call_block.skp.unit := amc$skip_tape_mark;
    amp$access_method (file_identifier, skip_call_block, global_layer_number, status);
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting AT_EOI to FALSE');
    tape_descriptor^.at_eoi := FALSE;
    bov_position := FALSE;

  PROCEND sl_advance_tapemark;
?? OLDTITLE ??
?? NEWTITLE := '    sl_advance_volume', EJECT ??

  PROCEDURE sl_advance_volume
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      label_group: fst$ansi_label_kinds,
      volume_position: amt$volume_position;

    status.normal := TRUE;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_ADVANCE_VOLUME');
    bai$advance_volume (file_identifier, volume_position, status);
    rmp$log_debug_status (status);
    tape_descriptor^.volume_position := volume_position;
    IF volume_position = amc$mid_bov_label_group THEN
      bov_position := TRUE;
    ELSE
      bov_position := FALSE;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_ADVANCE_VOLUME');

  PROCEND sl_advance_volume;
?? OLDTITLE ??
?? NEWTITLE := '    sl_authorize_access', EJECT ??

  PROCEDURE sl_authorize_access
    (    file_identifier: amt$file_identifier;
         label_group: fst$ansi_label_kinds;
         read_tape_labels_status: ost$status;
     VAR status: ost$status);

?? NEWTITLE := '    authorize_file_access', EJECT ??

    PROCEDURE authorize_file_access
      (VAR status: ost$status);

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling AUTHORIZE_FILE_ACCESS');

      tape_security_call_block.operation := fsc$ts_authorize_file_access;
      tape_security_call_block.authorize_file_access.header_labels := last_accessed_header_labels;
      #UNCHECKED_CONVERSION (file_instance^.instance_attributes.dynamic_label.access_mode,
            file_access_options);
      tape_security_call_block.authorize_file_access.proposed_access := file_access_options;
      tape_security_call_block.authorize_file_access.proposed_access_defaulted :=
            (file_instance^.instance_attributes.dynamic_label.access_mode_source = amc$access_method_default);
      tape_security_call_block.authorize_file_access.authorized_access := ^authorized_access;

      sl_enforce_tape_security (file_identifier, tape_security_call_block, status);

      IF status.normal THEN
        sl_store_authorized_access (authorized_access, status);
      IFEND;
    PROCEND authorize_file_access;
?? OLDTITLE ??
?? NEWTITLE := '      classify_tape_volume', EJECT ??

    PROCEDURE classify_tape_volume
      (    file_identifier: amt$file_identifier;
           read_tape_labels_status: ost$status;
       VAR classification: rmt$tape_volume_classification;
       VAR status: ost$status);

{Design: It is not sufficient to judge a volume to be blank labeled solely on the
{ content of the volume header labels.  This procedure attempts to read beyond the
{ volume label group.  If a tapemark is encountered, as expected, the classification
{ is retained.  If more labels are encountered after the volume header labels, the
{ volume is considered damaged and access is restricted.  If data is encountered,
{ the volume is no longer considered blank.

      VAR
        backspace_count: 1 .. 2,
        call_block: amt$call_block,
        formatted_classification: ost$status_message,
        local_status: ost$status,
        read_tape_labels: amt$read_tape_labels;

      status.normal := TRUE;

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering classify_tape_volume');
      rmp$classify_tape_volume (read_tape_labels_status, tape_descriptor^.last_accessed.
            unsecured_header_labels, classification, status);
      IF status.normal THEN
        IF rmv$tape_debug_mode THEN
          rmp$format_vol_classification ({max_message_line} 80, classification, formatted_classification,
                local_status);
          IF local_status.normal THEN
            log_volume_classification (formatted_classification);
          IFEND;
        IFEND;
        IF (classification.volume_label_type = rmc$labeled_volume_type) AND classification.labeled.blank THEN
          { VOL1 HDR1 HDR2 *
          {                 ^
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Initially classified labeled and blank');
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling read tape labels to see for sure');
          call_block.operation := amc$read_tape_labels;
          call_block.read_tape_labels := ^read_tape_labels;
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to read labels');
          amp$access_method (file_identifier, call_block, global_layer_number, local_status);
          rmp$log_debug_status (local_status);

          IF local_status.normal THEN {ERROR - missing a tapemark}
            { VOL1 HDR1 HDR2 * EOF1 EOF2 *  *
            {                             ^
            backspace_count := 2;
            classification.labeled.blank := FALSE;
            classification.labeled.volume_security_type := rmc$vst_access_restricted;
            classification.labeled.reason := rmc$excessive_tape_labels;
            rmp$log_debug_message ('Classified labeled, nonblank, damaged - missing tmk1');
          ELSE
            CASE local_status.condition OF
            = ame$invalid_tape_label =
              { VOL1 HDR1 HDR2 *  data
              {                        ^
              backspace_count := 1;
              classification.blank := FALSE;
              rmp$log_debug_message ('Classified labeled and nonblank');
            = ame$unexpected_tapemark =
              { VOL1 HDR1 HDR2 *  *
              {                    ^
              backspace_count := 2;

              rmp$log_debug_message ('Classified labeled and blank - retained original classification');
            = ame$excessive_tape_labels, ame$unexpected_tape_label, ame$tape_label_read_error =
              { VOL1 HDR1 HDR2 data blocks *
              {                             ^
              backspace_count := 1;
              classification.labeled.blank := FALSE;
              classification.labeled.volume_security_type := rmc$vst_access_restricted;
              classification.labeled.reason := rmc$excessive_tape_labels;
              rmp$log_debug_message ('Classified labeled, nonblank, damaged - missing tmk2');
            ELSE
            CASEND;
          IFEND;
          { VOL1 HDR1 HDR2 *
          {                 ^
          local_status.normal := TRUE;
          sl_advance_tapemark (file_identifier, amc$backward, backspace_count, local_status);
          { VOL1 HDR1 HDR2 *
          {               ^
          IF local_status.normal THEN
            sl_advance_tapemark (file_identifier, amc$forward, 1, local_status);
            { VOL1 HDR1 HDR2 *
            {                 ^
          IFEND;
        IFEND;
      IFEND;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting classify_tape_volume');
    PROCEND classify_tape_volume;
?? OLDTITLE ??
?? NEWTITLE := '      log_volume_classification', EJECT ??

    PROCEDURE log_volume_classification
      (    formatted_message: ost$status_message);

      VAR
        line_count_p: ^ost$status_message_line_count,
        line_number: ost$status_message_line_count,
        line_size_p: ^ost$status_message_line_size,
        line_text_p: ^string ( * <= osc$status_message_width),
        lines: ost$status_message_line_count,
        local_status: ost$status,
        message_p: ^ost$status_message,
        tape_security_state: bat$tape_validation_state;

      message_p := ^formatted_message;
      RESET message_p;

      NEXT line_count_p IN message_p;
      IF line_count_p <> NIL THEN
        bap$get_tape_security_state (tape_security_state, local_status);
        IF local_status.normal AND (NOT avp$removable_media_admin ()) AND
              (tape_security_state = bac$tape_validation_on) THEN
          lines := 4;
        ELSE
          lines := line_count_p^;
        IFEND;
        FOR line_number := 1 TO lines DO
          NEXT line_size_p IN message_p;
          NEXT line_text_p: [line_size_p^] IN message_p;
          rmp$log_debug_message (line_text_p^);
        FOREND;
      IFEND;

    PROCEND log_volume_classification;
?? OLDTITLE, EJECT ??

    VAR
      authorized_access: fst$file_access_options,
      classification: rmt$tape_volume_classification,
      file_access_options: fst$file_access_options,
      file_set_access: fst$file_access_options,
      initial_vol_sequence: ^SEQ ( * ),
      initial_header_labels: ^SEQ ( * ),
      last_accessed_sequence: ^SEQ ( * ),
      last_accessed_header_labels: ^SEQ ( * ),
      sequence_header: ^fst$tape_label_sequence_header,
      tape_security_call_block: fst$tape_security_call_block;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_AUTHORIZE_ACCESS');

    IF tape_descriptor^.initial_volume.header_labels <> NIL THEN
      initial_vol_sequence := tape_descriptor^.initial_volume.header_labels;
      RESET initial_vol_sequence;
      NEXT sequence_header IN initial_vol_sequence;
      PUSH initial_header_labels: [[REP sequence_header^.sequence_size OF cell]];
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Copying initial_header_labels');
      initial_header_labels^ := initial_vol_sequence^;
    ELSE
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Copying initial_header_labels=NIL');
      initial_header_labels := NIL;
    IFEND;

    IF tape_descriptor^.last_accessed.unsecured_header_labels <> NIL THEN
      last_accessed_sequence := tape_descriptor^.last_accessed.unsecured_header_labels;
      RESET last_accessed_sequence;
      NEXT sequence_header IN last_accessed_sequence;
      PUSH last_accessed_header_labels: [[REP sequence_header^.sequence_size OF cell]];
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Copying last_accessed_header_labels');
      last_accessed_header_labels^ := last_accessed_sequence^;
    ELSE
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Last_accessed_header_labels=NIL');
      last_accessed_header_labels := NIL;
    IFEND;

    IF fsp$volume_header_labels (label_group) OR (NOT read_tape_labels_status.normal) THEN
      classify_tape_volume (file_identifier, read_tape_labels_status, classification, status);
      IF status.normal THEN
        IF (tape_descriptor^.volume_number = 1) THEN
          {Ensure that invalid fields such as VOL1 II are not carried forth if labels are rewritten}
          bap$store_unsecured_tape_labels (last_accessed_header_labels,
                tape_descriptor^.initial_volume.header_labels);
          IF tape_descriptor^.initial_volume.initial_read_labels_attempt THEN
            tape_descriptor^.initial_volume.classification := classification;
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling AUTHORIZE_FILE_SET_MOUNT');
            tape_security_call_block.operation := fsc$ts_authorize_file_set_mount;
            tape_security_call_block.authorize_file_set_mount.access_method :=
                  tape_descriptor^.file_label_type;
            tape_security_call_block.authorize_file_set_mount.header_labels := initial_header_labels;
            #UNCHECKED_CONVERSION (file_instance^.instance_attributes.dynamic_label.access_mode,
                  file_access_options);
            tape_security_call_block.authorize_file_set_mount.proposed_access := file_access_options;
            tape_security_call_block.authorize_file_set_mount.proposed_access_defaulted :=
                  (file_instance^.instance_attributes.dynamic_label.access_mode_source =
                  amc$access_method_default);
            tape_security_call_block.authorize_file_set_mount.volume_classification :=
                  tape_descriptor^.initial_volume.classification;
            tape_security_call_block.authorize_file_set_mount.authorized_access := ^authorized_access;
            tape_security_call_block.authorize_file_set_mount.file_set_access := ^file_set_access;
            sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
            IF status.normal THEN
              tape_descriptor^.initial_volume.access_modes := file_set_access;
              sl_store_authorized_access (authorized_access, status);
              tape_descriptor^.initial_volume.initial_read_labels_attempt := FALSE;
            IFEND;
          ELSEIF read_tape_labels_status.normal THEN
            authorize_file_access (status);
          ELSE
            status := read_tape_labels_status;
          IFEND;
        ELSEIF NOT (state_info^.put_op OR state_info^.eoi_labels_needed) THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling AUTHORIZE_SECTION_READ');
          tape_security_call_block.operation := fsc$ts_authorize_section_read;
          tape_security_call_block.authorize_section_read.current_header_labels :=
                last_accessed_header_labels;
          tape_security_call_block.authorize_section_read.current_volume_classification := classification;
          tape_security_call_block.authorize_section_read.file_section_number :=
                tape_descriptor^.next_position.file_section_number;
          tape_security_call_block.authorize_section_read.file_sequence_number :=
                tape_descriptor^.next_position.file_sequence_number;
          tape_security_call_block.authorize_section_read.initial_volume_classification :=
                tape_descriptor^.initial_volume.classification;
          tape_security_call_block.authorize_section_read.initial_volume_header_labels :=
                initial_header_labels;
          sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
        IFEND;
      IFEND;
    ELSE
      authorize_file_access (status);
    IFEND;
    IF (NOT status.normal) AND (NOT sl_irrelevant_condition (status)) THEN
      sl_tape_abnormal_termination (file_identifier);
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_AUTHORIZE_ACCESS');

  PROCEND sl_authorize_access;
?? OLDTITLE ??
?? NEWTITLE := '    sl_authorize_access_method', EJECT ??

  PROCEDURE sl_authorize_access_method
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      ignore_label_group: fst$ansi_label_kinds,
      ignore_status: ost$status;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_AUTHORIZE_ACCESS_METHOD');
    status.normal := TRUE;
    sl_read_tape_labels (file_identifier, ignore_label_group, status);
    IF status.normal THEN
      rewind_tape (file_identifier, ignore_status);
    ELSE
      rmp$log_debug_status (status);
      sl_tape_abnormal_termination (file_identifier);
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_AUTHORIZE_ACCESS_METHOD');

  PROCEND sl_authorize_access_method;
?? OLDTITLE ??
?? NEWTITLE := '    sl_authorize_write_access', EJECT ??

  PROCEDURE sl_authorize_write_access
    (    file_identifier: amt$file_identifier;
         proposed_header_labels: ^SEQ ( * );
         writing_vol1_label: boolean;
     VAR status: ost$status);

    VAR
      authorized_access: fst$file_access_options,
      file_access_options: fst$file_access_options,
      file_set_access: fst$file_access_options,
      ignore_read_labels_status: ost$status,
      initial_vol_sequence: ^SEQ ( * ),
      initial_volume_header_labels: ^SEQ ( * ),
      last_accessed_sequence: ^SEQ ( * ),
      last_accessed_header_labels: ^SEQ ( * ),
      proposed_volume_classification: rmt$tape_volume_classification,
      sequence_header: ^fst$tape_label_sequence_header,
      tape_security_call_block: fst$tape_security_call_block;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_AUTHORIZE_WRITE_ACCESS');

    IF tape_descriptor^.initial_volume.header_labels <> NIL THEN
      initial_vol_sequence := tape_descriptor^.initial_volume.header_labels;
      RESET initial_vol_sequence;
      NEXT sequence_header IN initial_vol_sequence;
      PUSH initial_volume_header_labels: [[REP sequence_header^.sequence_size OF cell]];
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Copying initial_volume_header_labels');
      initial_volume_header_labels^ := initial_vol_sequence^;
    ELSE
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: initial_volume_header_labels = NIL');
      initial_volume_header_labels := NIL;
    IFEND;
    IF tape_descriptor^.last_accessed.unsecured_header_labels <> NIL THEN
      last_accessed_sequence := tape_descriptor^.last_accessed.unsecured_header_labels;
      RESET last_accessed_sequence;
      NEXT sequence_header IN last_accessed_sequence;
      PUSH last_accessed_header_labels: [[REP sequence_header^.sequence_size OF cell]];
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Copying last_accessed_header_labels');
      last_accessed_header_labels^ := last_accessed_sequence^;
    ELSE
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: last_accessed_header_labels = NIL');
      last_accessed_header_labels := NIL;
    IFEND;

    IF writing_vol1_label THEN
      IF tape_descriptor^.volume_number = 1 THEN
        IF tape_descriptor^.tape_attachment_information.volume_initialization THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling AUTHORIZE_VOLUME_REUSE');
          tape_security_call_block.operation := fsc$ts_authorize_volume_reuse;
          tape_security_call_block.authorize_volume_reuse.current_header_labels :=
                initial_volume_header_labels;
          tape_security_call_block.authorize_volume_reuse.proposed_file_label_type :=
                tape_descriptor^.file_label_type;
          tape_security_call_block.authorize_volume_reuse.proposed_blank_labels := proposed_header_labels;
          sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
          IF status.normal THEN
            bap$store_unsecured_tape_labels (proposed_header_labels,
                  tape_descriptor^.initial_volume.header_labels);
          IFEND;
        ELSE
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling AUTHORIZE_FILE_SET_REUSE');
          ignore_read_labels_status.normal := TRUE;
          rmp$classify_tape_volume (ignore_read_labels_status, proposed_header_labels,
                proposed_volume_classification, status);
          IF status.normal THEN
            tape_security_call_block.operation := fsc$ts_authorize_file_set_reuse;
            tape_security_call_block.authorize_file_set_reuse.initial_volume_classification :=
                  tape_descriptor^.initial_volume.classification;
            tape_security_call_block.authorize_file_set_reuse.initial_volume_header_labels :=
                  initial_volume_header_labels;
            #UNCHECKED_CONVERSION (file_instance^.instance_attributes.dynamic_label.access_mode,
                  file_access_options);
            file_access_options := file_access_options * tape_descriptor^.initial_volume.access_modes;
            tape_security_call_block.authorize_file_set_reuse.proposed_access := file_access_options;
            tape_security_call_block.authorize_file_set_reuse.proposed_volume_classification :=
                  proposed_volume_classification;
            tape_security_call_block.authorize_file_set_reuse.proposed_access_defaulted :=
                  (file_instance^.instance_attributes.dynamic_label.access_mode_source =
                  amc$access_method_default);
            tape_security_call_block.authorize_file_set_reuse.proposed_header_labels :=
                  proposed_header_labels;
            tape_security_call_block.authorize_file_set_reuse.authorized_access := ^authorized_access;
            tape_security_call_block.authorize_file_set_reuse.file_set_access := ^file_set_access;
            sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
            IF status.normal THEN
              tape_descriptor^.initial_volume.access_modes := file_set_access;
              tape_descriptor^.initial_volume.classification := proposed_volume_classification;
              sl_store_authorized_access (authorized_access, status);
              bap$store_unsecured_tape_labels (proposed_header_labels,
                    tape_descriptor^.initial_volume.header_labels);
            IFEND;
          IFEND;
        IFEND;
      ELSE
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling AUTHORIZE_SECTION_WRITE');
        tape_security_call_block.operation := fsc$ts_authorize_section_write;
        tape_security_call_block.authorize_section_write.current_header_labels := last_accessed_header_labels;
        tape_security_call_block.authorize_section_write.initial_volume_classification :=
              tape_descriptor^.initial_volume.classification;
        tape_security_call_block.authorize_section_write.initial_volume_header_labels :=
              initial_volume_header_labels;
        sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
      IFEND;
    ELSEIF tape_descriptor^.labeled_volume_position = bac$lvp_before_header_labels THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling AUTHORIZE_FILE_REUSE');
      tape_security_call_block.operation := fsc$ts_authorize_file_reuse;
      tape_security_call_block.authorize_file_reuse.initial_volume_classification :=
            tape_descriptor^.initial_volume.classification;
      tape_security_call_block.authorize_file_reuse.initial_volume_header_labels :=
            initial_volume_header_labels;
      tape_security_call_block.authorize_file_reuse.original_header_labels := last_accessed_header_labels;
      tape_security_call_block.authorize_file_reuse.proposed_header_labels := proposed_header_labels;
      sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_AUTHORIZE_WRITE_ACCESS');
    IFEND;
    IF NOT status.normal THEN
      rmp$log_debug_status (status);
      sl_tape_abnormal_termination (file_identifier);
    IFEND;
  PROCEND sl_authorize_write_access;
?? OLDTITLE ??
?? NEWTITLE := '    sl_close_label_volume', EJECT ??

  PROCEDURE sl_close_label_volume
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      label_group: fst$ansi_label_kinds;

    status.normal := TRUE;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_CLOSE_LABEL_VOLUME');
    IF state_info^.put_op OR state_info^.eoi_labels_needed THEN
      sl_put_end_of_vol_labels (file_identifier, status);
      IF status.normal THEN
        sl_advance_volume (file_identifier, status);
        IF status.normal THEN
          sl_read_tape_labels (file_identifier, label_group, status);
          IF status.normal THEN
            sl_advance_tapemark (file_identifier, amc$backward, 2, status);
            IF (NOT status.normal) AND (status.condition = ame$skip_encountered_bov) THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Rewriting labels on volume overflow');
              sl_put_header_labels (file_identifier, {include_vol1_label=} TRUE, status);
              IF status.normal THEN
                IF state_info^.buffered_blocks = 0 THEN
                  gfi^.positioning_info.block_info.block_number := 1;
                  tape_descriptor^.volume_position := amc$after_tapemark;
                  bov_position := FALSE;
                  state_info^.put_op := FALSE;
                ELSE
                  gfi^.positioning_info.block_info.block_number := state_info^.buffered_blocks;
                  tape_descriptor^.volume_position := amc$after_data_block;
                  bov_position := FALSE;
                  state_info^.put_op := TRUE;
                IFEND;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    ELSE
      sl_advance_volume (file_identifier, status);
      IF status.normal THEN
        sl_read_tape_labels (file_identifier, label_group, status)
      IFEND;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_CLOSE_LABEL_VOLUME');
    rmp$log_debug_status (status);
  PROCEND sl_close_label_volume;
?? OLDTITLE ??
?? NEWTITLE := '    sl_decrement_file_sequence_no', EJECT ??

  PROCEDURE [INLINE] sl_decrement_file_sequence_no;

    IF tape_descriptor^.next_position.file_sequence_number > 1 THEN
      rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SEQUENCE_NUMBER was: ',
            tape_descriptor^.next_position.file_sequence_number);
      tape_descriptor^.next_position.file_sequence_number :=
            tape_descriptor^.next_position.file_sequence_number - 1;
      rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SEQUENCE_NUMBER decremented to: ',
            tape_descriptor^.next_position.file_sequence_number);
    IFEND;

  PROCEND sl_decrement_file_sequence_no;

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

  PROCEDURE sl_enable_read_after_write
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

{Design: The buffer manager maintains I/O operation status of read, write, or
{indeterminated.  When the direction of the tape reverses after writing, it is
{necessary to close and reopen the tape at the BM level to change the operational
{status.  Reading after writing is only allowed when the ANSI file is first rewound.
{But the operational status should be changed to indetermainate immediately after
{writing trailer labels to allow a subsequent rewind/get sequence to work.

    VAR
      ignore_failure_modes: amt$tape_failure_modes;

    status.normal := TRUE;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_ENABLE_READ_AFTER_WRITE');
    bap$tape_bm_close (file_identifier, ignore_failure_modes, status);
    IF status.normal THEN
      bap$tape_bm_open (file_identifier, gfi^.max_data_size, status);
    IFEND;

    IF NOT status.normal THEN
      CASE status.condition OF
      = bae$maxbl_exceeds_ws_limit =
        amp$set_file_instance_abnormal (file_identifier, ame$maxbl_exceeds_ws_limit, operation, '', status);
      = bae$tape_block_mgr_malfunction =
        amp$set_file_instance_abnormal (file_identifier, ame$tape_block_mgr_malfunction, operation,
              status.text.value (2, status.text.size - 1), status);
      = bae$tape_driver_not_capable =
        amp$set_file_instance_abnormal (file_identifier, ame$tape_driver_not_capable, operation, '', status);
      ELSE
      CASEND;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_ENABLE_READ_AFTER_WRITE');

  PROCEND sl_enable_read_after_write;
?? OLDTITLE ??
?? NEWTITLE := '    sl_enforce_tape_security', EJECT ??

  PROCEDURE sl_enforce_tape_security
    (    file_identifier: amt$file_identifier;
     VAR tape_security_call_block {input, output} : fst$tape_security_call_block;
     VAR status: ost$status);

    VAR
      call_block: amt$call_block,
      enforce_tape_security: boolean,
      local_status: ost$status,
      tape_security_state: bat$tape_validation_state;

    status.normal := TRUE;

    call_block.operation := amc$enforce_tape_security;
    call_block.enforce_tape_security := #SEQ (tape_security_call_block);
    CASE tape_security_call_block.operation OF
    = fsc$ts_authorize_access_method, fsc$ts_authorize_file_access, fsc$ts_authorize_file_reuse,
          fsc$ts_authorize_section_write, fsc$ts_authorize_file_set_mount, fsc$ts_authorize_file_set_reuse,
          fsc$ts_authorize_section_read, fsc$ts_authorize_volume_reuse =
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling bap$get_tape_security_state');
      bap$get_tape_security_state (tape_security_state, local_status);
      enforce_tape_security := (tape_security_state = bac$tape_validation_on);
      IF enforce_tape_security THEN
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Tape security state is ON');
      ELSE
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Tape security state is OFF');
      IFEND;
      CASE tape_security_call_block.operation OF
      = fsc$ts_authorize_access_method =
        tape_security_call_block.authorize_access_method.enforce_tape_security := enforce_tape_security;
      = fsc$ts_authorize_file_access =
        tape_security_call_block.authorize_file_access.enforce_tape_security := enforce_tape_security;
      = fsc$ts_authorize_file_reuse =
        tape_security_call_block.authorize_file_reuse.enforce_tape_security := enforce_tape_security;
      = fsc$ts_authorize_section_write =
        tape_security_call_block.authorize_section_write.enforce_tape_security := enforce_tape_security;
      = fsc$ts_authorize_file_set_mount =
        tape_security_call_block.authorize_file_set_mount.enforce_tape_security := enforce_tape_security;
      = fsc$ts_authorize_file_set_reuse =
        tape_security_call_block.authorize_file_set_reuse.enforce_tape_security := enforce_tape_security;
      = fsc$ts_authorize_section_read =
        tape_security_call_block.authorize_section_read.enforce_tape_security := enforce_tape_security;
      = fsc$ts_authorize_volume_reuse =
        tape_security_call_block.authorize_volume_reuse.enforce_tape_security := enforce_tape_security;
      ELSE
      CASEND;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling amp$access_method - authorize');
      amp$access_method (file_identifier, call_block, global_layer_number, status);
    = fsc$ts_secure_header_labels, fsc$ts_secure_trailer_labels, fsc$ts_validate_header_labels,
          fsc$ts_validate_trailer_labels =
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling amp$access_method - secure or validate');
      amp$access_method (file_identifier, call_block, global_layer_number, status);
    CASEND;

  PROCEND sl_enforce_tape_security;
?? OLDTITLE ??
?? NEWTITLE := '    sl_find_next_header_group', EJECT ??

  PROCEDURE sl_find_next_header_group
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

{Design: On entry, the tape could be positioned just about anywhere, including the
{end of the volume set.  We may have to skip over embedded tapemarks to get to the
{next header label group.
{
{The end of a file set is signaled by a single tapemark following an EOF label group.
{If the starting position is after an EOF label group, we can only read one tapemark
{beyond the current position for fear of reading beyond the end of recorded data on
{the volume.  If the volume does not adhere to ANSI convention, we will stop if 3
{consecutive tapemarks are encountered.  We always backspace over consecutive tapemarks
{that we read when we exit due to reaching end of set.

    VAR
      consecutive_tapemarks_read: 0 .. 3,
      ignore_status: ost$status,
      label_group: fst$ansi_label_kinds,
      after_labels: boolean;

    status.normal := TRUE;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_FIND_NEXT_HEADER_GROUP');
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));
    consecutive_tapemarks_read := 0;
    after_labels := sl_after_label_group (tape_descriptor^.labeled_volume_position);
    CASE tape_descriptor^.labeled_volume_position OF
    = bac$lvp_end_of_file_set, bac$lvp_end_of_volume_list =
      osp$set_status_condition (ame$file_not_in_volume_set, status);
      osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
    = bac$lvp_after_header_labels =
      IF NOT (tape_descriptor^.initial_volume.classification.labeled.blank) THEN
        sl_advance_tapemark (file_identifier, amc$forward, 1, status);
        IF status.normal THEN
          consecutive_tapemarks_read := 1;
        IFEND;
      IFEND;
    = bac$lvp_within_ansi_file =
      sl_advance_tapemark (file_identifier, amc$forward, 1, status);
      IF status.normal THEN
        consecutive_tapemarks_read := 1;
      IFEND;
    ELSE
    CASEND;
    IF status.normal THEN
      REPEAT
        {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
        {                ^
        sl_read_tape_labels (file_identifier, label_group, status);
        IF status.normal THEN
          IF fsp$header_labels (label_group) THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_FIND_NEXT_HEADER_GROUP - success');
            RETURN; {----->
          ELSEIF fsp$file_trailer_labels (label_group) THEN
            consecutive_tapemarks_read := 0;
            after_labels := TRUE;
          ELSEIF fsp$volume_trailer_labels (label_group) THEN
            sl_advance_volume (file_identifier, status);
            IF status.normal THEN
              consecutive_tapemarks_read := 0;
              after_labels := TRUE;
            IFEND;
          IFEND;
        ELSE
          CASE status.condition OF
          = ame$invalid_tape_label =
            {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
            {                             ^
            sl_advance_tapemark (file_identifier, amc$forward, 1, status);
            {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
            {                                  ^
            IF status.normal THEN
              consecutive_tapemarks_read := 1;
              after_labels := FALSE;
            IFEND;
          = ame$unexpected_tapemark =
            consecutive_tapemarks_read := consecutive_tapemarks_read + 1;
            IF (after_labels AND (consecutive_tapemarks_read = 1)) OR (consecutive_tapemarks_read = 3) THEN
              {   * EOF1 EOF2 * HDR1 HDR2* data * data * EOF1 EOF2* * *
              {                                                        ^
              sl_advance_tapemark (file_identifier, amc$backward, consecutive_tapemarks_read, ignore_status);
              {   HDR1 HDR2* data * data * EOF1 EOF2* * *
              {                                      ^
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to end of file set');
              tape_descriptor^.labeled_volume_position := bac$lvp_end_of_file_set;
              tape_descriptor^.volume_position := amc$after_tapemark;
              state_info^.put_op := FALSE;
              file_instance^.previous_get_at_eoi := FALSE;
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_FIND_NEXT_HEADER_GROUP - hit EOS');
              osp$set_status_condition (ame$file_not_in_volume_set, status);
              osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
              RETURN; {----->
            ELSE
              {   * EOF1 EOF2 * HDR1 HDR2* data * data * EOF1 EOF2*
              {                                  ^
              status.normal := TRUE;
            IFEND;
          ELSE
          CASEND;
        IFEND;
      UNTIL NOT status.normal;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_FIND_NEXT_HEADER_GROUP - abnormal');
    rmp$log_debug_status (status);
  PROCEND sl_find_next_header_group;
?? OLDTITLE ??
?? NEWTITLE := '    sl_find_next_trailer_group', EJECT ??

  PROCEDURE sl_find_next_trailer_group
    (    file_identifier: amt$file_identifier;
     VAR label_group: fst$ansi_label_kinds;
     VAR status: ost$status);

{Design: On entry, the tape could be positioned just about anywhere, including the
{end of the volume set.  We may have to skip over embedded tapemarks to find the
{next trailer label group.
{
{The end of a file set is signaled by a single tapemark following a label group.
{If the starting position is after a label group, we can only read one tapemark
{beyond the current position for fear of reading beyond the end of recorded data on
{the volume.  If the ANSI file contains embedded tapemarks, we will stop if 3
{consecutive tapemarks are encountered.  We always backspace over consecutive tapemarks
{that we read when we exit due to reaching end of set.

    VAR
      consecutive_tapemarks_read: 0 .. 3,
      ignore_status: ost$status,
      after_labels: boolean;

    {   * EOF1 EOF2* HDR1 HDR2* data * EOF1 EOF2* * *
    {               ?             ?              ?
    status.normal := TRUE;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_FIND_NEXT_TRAILER_GROUP');
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));
    consecutive_tapemarks_read := 0;
    after_labels := sl_after_label_group (tape_descriptor^.labeled_volume_position);
    CASE tape_descriptor^.labeled_volume_position OF
    = bac$lvp_end_of_file_set =
      osp$set_status_condition (ame$file_not_in_volume_set, status);
      osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
      RETURN; {----->

    = bac$lvp_within_ansi_file =
      sl_advance_tapemark (file_identifier, amc$forward, 1, status);
      IF status.normal THEN
        consecutive_tapemarks_read := 1;
      IFEND;
    ELSE
    CASEND;

  /find_trailer/
    REPEAT
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling sl_read_tape_labels');
      sl_read_tape_labels (file_identifier, label_group, status);
      IF status.normal OR sl_irrelevant_condition (status) THEN
        status.normal := TRUE;
        IF fsp$trailer_labels (label_group) THEN
          RETURN; {----->
        ELSEIF fsp$volume_header_labels (label_group) AND (tape_descriptor^.volume_number = 1) AND
              (tape_descriptor^.initial_volume.classification.volume_label_type = rmc$labeled_volume_type) AND
              (tape_descriptor^.initial_volume.classification.labeled.blank) THEN
          {An initialized volume may, according to ANSI, consist of a VOL1 label followed by as few as two
          {tapemarks.  Avoid skipping or reading beyond the recorded area of the tape.
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Blank volume - hit EOS');
          osp$set_status_condition (ame$file_not_in_volume_set, status);
          RETURN; {----->
        ELSEIF fsp$header_labels (label_group) THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Header labels were read');
          sl_advance_tapemark (file_identifier, amc$forward, 1, status);
          rmp$log_debug_status (status);
          {
          {   HDR1 HDR2* data * EOF1 EOF2*
          {                    ^
          consecutive_tapemarks_read := 1;
          after_labels := FALSE;
          CYCLE /find_trailer/; {----->
        IFEND;
      ELSE
        CASE status.condition OF
        = ame$invalid_tape_label =
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Found data block?');
          { We must have encountered a data block after a tapemark
          {   HDR1 HDR2* data * data * EOF1 EOF2*
          {                     ^
          sl_advance_tapemark (file_identifier, amc$forward, 1, status);
          {
          {   HDR1 HDR2* data * data * EOF1 EOF2*
          {                           ^
          IF status.normal THEN
            tape_descriptor^.volume_position := amc$after_tapemark;
            consecutive_tapemarks_read := 1;
            after_labels := FALSE;
          IFEND;
        = ame$unexpected_tapemark =
          consecutive_tapemarks_read := consecutive_tapemarks_read + 1;
          IF (after_labels AND (consecutive_tapemarks_read = 2)) OR (consecutive_tapemarks_read = 3) THEN
            sl_advance_tapemark (file_identifier, amc$backward, consecutive_tapemarks_read, ignore_status);
            {   HDR1 HDR2* data * data * EOF1 EOF2* * *
            {                                      ^
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to end of file set');
            tape_descriptor^.labeled_volume_position := bac$lvp_end_of_file_set;
            tape_descriptor^.volume_position := amc$after_tapemark;
            state_info^.put_op := FALSE;
            file_instance^.previous_get_at_eoi := FALSE;
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_FIND_NEXT_TRAILER_GROUP - hit EOS');
            osp$set_status_condition (ame$file_not_in_volume_set, status);
            osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
            RETURN; {----->
          ELSE {Could be embedded tapemark, try once more}
            {
            {   HDR1 HDR2* data * data * EOF1 EOF2* * *
            {                                        ^
            status.normal := TRUE;
          IFEND;
        ELSE
        CASEND;
      IFEND;
    UNTIL NOT status.normal;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_FIND_NEXT_TRAILER_GROUP - abnormal status');
    rmp$log_debug_status (status);

  PROCEND sl_find_next_trailer_group;
?? OLDTITLE ??
?? NEWTITLE := '    sl_increment_file_sequence_no', EJECT ??

  PROCEDURE [INLINE] sl_increment_file_sequence_no;

{Design: The ANSI standard limits the number of ANSI files on a volume set to 9999.
{Our implementation increments the NEXT_POSITION file sequence number after trailer
{labels are written or read.  If we have just accessed the last possible ANSI file,
{the NEXT_POSITION value is left at 9999.  Setting the labeled_volume_position to
{END_OF_VOLUME_SET prevents further writing of ANSI files.

    IF tape_descriptor^.next_position.file_sequence_number < 9999 THEN
      rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SEQUENCE_NUMBER was: ',
            tape_descriptor^.next_position.file_sequence_number);
      tape_descriptor^.next_position.file_sequence_number :=
            tape_descriptor^.next_position.file_sequence_number + 1;
      rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SEQUENCE_NUMBER incremented to: ',
            tape_descriptor^.next_position.file_sequence_number);
    ELSE
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to end of volume set');
      tape_descriptor^.labeled_volume_position := bac$lvp_end_of_volume_list;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting AT_EOI to TRUE');
      tape_descriptor^.at_eoi := TRUE;
    IFEND;

  PROCEND sl_increment_file_sequence_no;

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

  PROCEDURE sl_log_eof_block_count
    (    block_count: 0 .. 999999;
         mode: string ( * ));

    VAR
      ignore_status: ost$status,
      local_status: ost$status;

    osp$set_status_condition (ame$log_eof_block_count, local_status);
    osp$append_status_parameter (osc$status_parameter_delimiter, mode, local_status);
    osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, local_status);
    osp$append_status_integer (osc$status_parameter_delimiter,
          tape_descriptor^.next_position.file_sequence_number, 10, FALSE, local_status);
    osp$append_status_integer (osc$status_parameter_delimiter,
          tape_descriptor^.next_position.file_section_number, 10, FALSE, local_status);
    osp$append_status_integer (osc$status_parameter_delimiter, block_count, 10, FALSE, local_status);
    osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], local_status, ignore_status);

  PROCEND sl_log_eof_block_count;
?? OLDTITLE ??
?? NEWTITLE := '    sl_log_eov_block_count', EJECT ??

  PROCEDURE sl_log_eov_block_count
    (    block_count: 0 .. 999999;
         mode: string ( * ));

    VAR
      ignore_status: ost$status,
      local_status: ost$status;

    osp$set_status_condition (ame$log_eov_block_count, local_status);
    osp$append_status_parameter (osc$status_parameter_delimiter, mode, local_status);
    osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, local_status);
    osp$append_status_integer (osc$status_parameter_delimiter,
          tape_descriptor^.next_position.file_sequence_number, 10, FALSE, local_status);
    osp$append_status_integer (osc$status_parameter_delimiter,
          tape_descriptor^.next_position.file_section_number, 10, FALSE, local_status);
    osp$append_status_integer (osc$status_parameter_delimiter, block_count, 10, FALSE, local_status);
    osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], local_status, ignore_status);

  PROCEND sl_log_eov_block_count;
?? OLDTITLE ??
?? NEWTITLE := '    sl_after_label_group', EJECT ??

  FUNCTION [INLINE] sl_after_label_group
    (    labeled_volume_position: bat$labeled_volume_position): boolean;

{ This function determines whether we are positioned after a label group.

    CASE labeled_volume_position OF
    = bac$lvp_after_header_labels, bac$lvp_after_trailer_labels, bac$lvp_end_of_file_set,
          bac$lvp_end_of_volume_list =
      sl_after_label_group := TRUE;
    = bac$lvp_beginning_of_file_set, bac$lvp_within_ansi_file =
      sl_after_label_group := FALSE;
    CASEND;

  FUNCEND sl_after_label_group;

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

  FUNCTION [INLINE] sl_irrelevant_condition
    (    status: ost$status): boolean;

{ This function identifies certain exception conditions as irrelevant.
{ These conditions are considered irrelevant when they are detected during the
{ positioning of a volume set prior to finding the target ANSI file.

    sl_irrelevant_condition := FALSE;
    IF NOT status.normal THEN
      CASE status.condition OF
      = ame$ansi_file_unexpired, ame$insufficient_file_access =
        sl_irrelevant_condition := TRUE;
      ELSE
      CASEND;
    IFEND;

  FUNCEND sl_irrelevant_condition;

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

  FUNCTION [INLINE] sl_next_position_is_last_file
    (    file_set_position: fst$tape_file_set_position;
         last_accessed_file_id: string (17);
         last_accessed_generation_no: 1 .. 9999): boolean;

{ This function determines whether the next position is the last ANSI file that
{ was accessed.  The next position file sequence number is only incremented after
{ trailer labels are read or written.  Therefore, if our current positon is after
{ trailer labels, the current ansi file sequence number is one less than the next
{ position value.

    VAR
      last_accessed_file_sequence: 1 .. 9999;

    sl_next_position_is_last_file := FALSE;
    CASE file_set_position.position OF
    = fsc$tape_file_sequence_pos =
      IF bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
        last_accessed_file_sequence := tape_descriptor^.next_position.file_sequence_number - 1;
        IF last_accessed_file_sequence = file_set_position.file_sequence_number THEN
          sl_next_position_is_last_file := TRUE;
        IFEND;
      ELSEIF (tape_descriptor^.next_position.file_sequence_number = file_set_position.file_sequence_number)
            THEN
        sl_next_position_is_last_file := TRUE;
      IFEND;
    = fsc$tape_file_identifier_pos =
      IF (last_accessed_file_id = file_set_position.file_identifier) AND
            (last_accessed_generation_no = file_set_position.generation_number) THEN
        sl_next_position_is_last_file := TRUE;
      IFEND;
    ELSE
    CASEND;

  FUNCEND sl_next_position_is_last_file;

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

  PROCEDURE sl_open_label_file
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
         local_file_name: amt$local_file_name;
     VAR status: ost$status);

?? NEWTITLE := '      adjust_file_attributes', EJECT ??

    PROCEDURE adjust_file_attributes
      (VAR status: ost$status);

      CONST
        bo = 1,
        bt = 2,
        cc = 3,
        cs = 4,
        ii = 5,
        mbl = 6,
        mrl = 7,
        pc = 8,
        rt = 9;

      VAR
        hdr2_label: ^fst$ansi_hdr2_label,
        instance_attrib: ^array [bo .. rt] of fst$attachment_option,
        label_identifier: fst$tape_label_identifier,
        label_locator: fst$tape_label_locator,
        returned_attributes: fst$tla_returned_attributes,
        tape_failure_modes: amt$tape_failure_modes;

      status.normal := TRUE;
      state_info^.ve_wrote_ansi_file := FALSE;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering ADJUST_FILE_ATTRIBUTES');
      PUSH instance_attrib;
      instance_attrib^ [bo].selector := fsc$tape_attachment;
      instance_attrib^ [bo].tape_attachment.selector := fsc$tape_buffer_offset;
      instance_attrib^ [bt].selector := fsc$tape_attachment;
      instance_attrib^ [bt].tape_attachment.selector := fsc$tape_block_type;
      instance_attrib^ [cc].selector := fsc$tape_attachment;
      instance_attrib^ [cc].tape_attachment.selector := fsc$tape_character_conversion;
      instance_attrib^ [cs].selector := fsc$tape_attachment;
      instance_attrib^ [cs].tape_attachment.selector := fsc$tape_character_set;
      instance_attrib^ [ii].selector := fsc$tape_attachment;
      instance_attrib^ [ii].tape_attachment.selector := fsc$tape_implementation_id;
      instance_attrib^ [mbl].selector := fsc$tape_attachment;
      instance_attrib^ [mbl].tape_attachment.selector := fsc$tape_max_block_length;
      instance_attrib^ [mrl].selector := fsc$tape_attachment;
      instance_attrib^ [mrl].tape_attachment.selector := fsc$tape_max_record_length;
      instance_attrib^ [pc].selector := fsc$tape_attachment;
      instance_attrib^ [pc].tape_attachment.selector := fsc$tape_padding_character;
      instance_attrib^ [rt].selector := fsc$tape_attachment;
      instance_attrib^ [rt].tape_attachment.selector := fsc$tape_record_type;

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FSP$GETTLA - last_accessed - for VE fields');
      fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_last_ansi_file_accessed,
            instance_attrib^, returned_attributes, status);

      IF status.normal THEN
        IF (fsc$tape_buffer_offset IN returned_attributes) AND
              (instance_attrib^ [bo].tape_attachment.tape_buffer_offset > 0) THEN
          osp$set_status_condition (ame$unimplemented_buffer_offset, status);
          osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
        IFEND;
      IFEND;
      IF status.normal THEN
        IF fsc$tape_character_conversion IN returned_attributes THEN
          IF state_info^.character_conversion THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing TRUE for Character Conversion');
          ELSE
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing FALSE for Character Conversion');
          IFEND;
          state_info^.character_conversion := instance_attrib^ [cc].tape_attachment.tape_character_conversion;
        IFEND;
        IF fsc$tape_character_set IN returned_attributes THEN
          CASE state_info^.character_set OF
          = amc$ascii =
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing ASCII for Character Set');
          = amc$ebcdic =
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing EBCDIC for Character Set');
          ELSE
            rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Storing OTHER Character Set=',
                  $INTEGER (state_info^.character_set));
          CASEND;
          state_info^.character_set := instance_attrib^ [cs].tape_attachment.tape_character_set;
        IFEND;
        IF fsc$tape_max_block_length IN returned_attributes THEN
          state_info^.maximum_block_length := instance_attrib^ [mbl].tape_attachment.tape_max_block_length;
          rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Stored MAXBL=', state_info^.maximum_block_length);
        IFEND;
        IF fsc$tape_max_record_length IN returned_attributes THEN
          state_info^.maximum_record_length := instance_attrib^ [mrl].tape_attachment.tape_max_record_length;
          rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Stored MAXRL=', state_info^.maximum_record_length);
        IFEND;
        IF fsc$tape_padding_character IN returned_attributes THEN
          state_info^.padding_character := instance_attrib^ [pc].tape_attachment.tape_padding_character;
        IFEND;
        IF fsc$tape_implementation_id IN returned_attributes THEN
          state_info^.ve_wrote_ansi_file := fsp$ve_wrote_ansi_file
                (instance_attrib^ [ii].tape_attachment.tape_implementation_id);
        IFEND;

        gfi^.max_data_size := state_info^.maximum_block_length;
        gfi^.max_block_size := state_info^.maximum_block_length;
        gfi^.max_record_length := state_info^.maximum_record_length;
        gfi^.padding_character := state_info^.padding_character;

        { Reject unsupported block_type/record_type combinations
        IF instance_attrib^ [bt].tape_attachment.tape_block_type = amc$user_specified THEN
          IF instance_attrib^ [rt].tape_attachment.tape_record_type = amc$trailing_char_delimited THEN
            amp$set_local_name_abnormal (local_file_name, ame$unsupported_tape_bt_rt, call_block.operation,
                  'Block type USER_SPECIFIED (US), record type TRAILING_CHARACTER_DELIMITED (T)', status);
          IFEND;
        ELSEIF instance_attrib^ [bt].tape_attachment.tape_block_type = amc$system_specified THEN
          IF instance_attrib^ [rt].tape_attachment.tape_record_type = amc$trailing_char_delimited THEN
            amp$set_local_name_abnormal (local_file_name, ame$unsupported_tape_bt_rt, call_block.operation,
                  'Block type SYSTEM_SPECIFIED (SS), record type TRAILING_CHARACTER_DELIMITED (T)', status);
          ELSEIF instance_attrib^ [rt].tape_attachment.tape_record_type = amc$ansi_fixed THEN
            amp$set_local_name_abnormal (local_file_name, ame$unsupported_tape_bt_rt, call_block.operation,
                  'Block type SYSTEM_SPECIFIED (SS), record type FIXED (F)', status);
          ELSEIF instance_attrib^ [rt].tape_attachment.tape_record_type = amc$ansi_variable THEN
            amp$set_local_name_abnormal (local_file_name, ame$unsupported_tape_bt_rt, call_block.operation,
                  'Block type SYSTEM_SPECIFIED (SS), record type ANSI_VARIABLE (D)', status);
          ELSEIF instance_attrib^ [rt].tape_attachment.tape_record_type = amc$ansi_spanned THEN
            amp$set_local_name_abnormal (local_file_name, ame$unsupported_tape_bt_rt, call_block.operation,
                  'Block type SYSTEM_SPECIFIED (SS), record type ANSI_SPANNED (S)', status);
          IFEND;
        IFEND;

        label_identifier.location_method := fsc$tape_label_locate_by_kind;
        label_identifier.label_kind := fsc$ansi_hdr2_label_kind;
        fsp$locate_tape_label (tape_descriptor^.last_accessed.unsecured_header_labels, label_identifier,
              label_locator);
        IF status.normal AND label_locator.label_found THEN
          RESET label_locator.label_block;
          NEXT hdr2_label IN label_locator.label_block;
          IF hdr2_label <> NIL THEN
            IF ((hdr2_label^.record_format = 'V') OR (hdr2_label^.record_format = 'v')) AND
                  NOT fsp$ve_wrote_ansi_file (instance_attrib^ [ii].tape_attachment.tape_implementation_id)
                  THEN
              {Convert IBM V record formatted tape to NOS/VE U/US format
              bap$change_tape_bt_and_rt (file_identifier, layer_number, amc$user_specified, amc$undefined,
                    status);
            ELSEIF (hdr2_label^.record_format <> ' ') OR ((hdr2_label^.ve_record_type <> ' ') AND
                  (hdr2_label^.ve_block_type <> ' ')) THEN
              bap$change_tape_bt_and_rt (file_identifier, layer_number,
                    instance_attrib^ [bt].tape_attachment.tape_block_type,
                    instance_attrib^ [rt].tape_attachment.tape_record_type, status);
            IFEND;

            IF status.normal THEN

              IF instance_attrib^ [bt].tape_attachment.tape_block_type = amc$system_specified THEN
                IF ($pft$usage_selections [pfc$shorten, pfc$append] *
                      file_instance^.instance_attributes.dynamic_label.access_mode) <>
                      $pft$usage_selections [] THEN
                  rmp$log_debug_integer ('LABELED_TAPE_DEBUG: REQUESTED_DENSITY=',
                        $INTEGER (tape_descriptor^.requested_density));
                  IF (tape_descriptor^.requested_density = rmc$38000) THEN
                    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting GFI max block size to 32640');
                    gfi^.max_data_size := 32640;
                    gfi^.max_block_size := 32640;
                  ELSE
                    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting GFI max block size to 4128');
                    gfi^.max_data_size := 4128;
                    gfi^.max_block_size := 4128;
                  IFEND;
                IFEND;
              ELSE
                rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Setting GFI max block size to ',
                      state_info^.maximum_block_length);
                gfi^.max_data_size := state_info^.maximum_block_length;
                gfi^.max_block_size := state_info^.maximum_block_length;
              IFEND;
{
{ Call the Block Manager to close and open the file in order to change the maximum block length.
{
              sl_enable_read_after_write (file_identifier, status);
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    PROCEND adjust_file_attributes;
?? OLDTITLE ??
?? NEWTITLE := '      implement_file_set_position', EJECT ??

    PROCEDURE implement_file_set_position
      (VAR rewrite_labels: boolean;
       VAR status: ost$status);

?? NEWTITLE := '        adjust_rewrite_labels', EJECT ??

      PROCEDURE adjust_rewrite_labels
        (VAR rewrite_labels: boolean);

{Design:
{A tape written by NOS/VE prior to L780 (R1.6.1) may have a blank label group at BOS
{but have files beyond the first one.  If writing at BOS on a such a volume, we force
{REWRITE_LABELS to TRUE to ensure that a blank label group is rewritten with a proper
{(nonblank) label group.  RMP$CLASSIFY_TAPE_VOLUME determines that the label group
{corresponds to a pre-L780 NOS/VE blank label group and classifies it as
{cdc_version_one, nonblank, with owner_identifier = ' '.  The code below ensures that
{all of the conditions that were checked by RMP$CLASSIFY_TAPE_VOLUME are still in effect.
{
{This allows files after the empty one to be read and allows random positioning beyond
{the first ANSI file.

        VAR
          hdr2_label: ^fst$ansi_hdr2_label,
          ignore_status: ost$status,
          label_identifier: fst$tape_label_identifier,
          label_locator: fst$tape_label_locator;

        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering ADJUST_REWRITE_LABELS');
        IF tape_descriptor^.initial_volume.classification.labeled.expired AND
              (NOT tape_descriptor^.initial_volume.classification.labeled.blank) AND
              (tape_descriptor^.initial_volume.classification.labeled.file_accessibility = ' ') AND
              (tape_descriptor^.initial_volume.classification.labeled.volume_accessibility = ' ') THEN
          IF (tape_descriptor^.initial_volume.classification.labeled.volume_security_type =
                rmc$vst_ve_password_protected) AND fsp$version_one_tape_label
                (tape_descriptor^.initial_volume.classification.labeled.implementation_identifier) AND
                (tape_descriptor^.initial_volume.classification.labeled.ve_owner_identifier = ' ') THEN
            label_identifier.location_method := fsc$tape_label_locate_by_kind;
            label_identifier.label_kind := fsc$ansi_hdr2_label_kind;
            fsp$locate_tape_label (tape_descriptor^.last_accessed.unsecured_header_labels, label_identifier,
                  label_locator);
            IF label_locator.label_found THEN
              RESET label_locator.label_block;
              NEXT hdr2_label IN label_locator.label_block;
              IF hdr2_label <> NIL THEN
                IF (hdr2_label^.record_format = ' ') AND (hdr2_label^.block_length = '00000') AND
                      (hdr2_label^.record_length = '00000') AND (hdr2_label^.ve_block_type = ' ') AND
                      (hdr2_label^.ve_record_type = ' ') AND (hdr2_label^.ve_block_length_ext = '000') AND
                      (hdr2_label^.ve_record_length_ext = '000') AND
                      (hdr2_label^.ve_padding_character = ' ') AND (hdr2_label^.ve_character_set = ' ') AND
                      (hdr2_label^.ve_character_conversion = ' ') THEN
                  rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting RL=TRUE for blank V1.0');
                  rewrite_labels := TRUE;
                  rewind_tape (file_identifier, ignore_status);
                IFEND;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting ADJUST_REWRITE_LABELS');

      PROCEND adjust_rewrite_labels;
?? OLDTITLE ??
?? NEWTITLE := '        position_to_end_of_set', EJECT ??

      PROCEDURE position_to_end_of_set
        (VAR status: ost$status);

        VAR
          ignore_label_group: fst$ansi_label_kinds,
          ignore_status: ost$status;

{Design: The volume could be positioned anywhere at the time this procedure is
{called.  We read file header labels until we encounter a tapemark which signals
{ end of set.

        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering POSITION_TO_END_OF_SET');
        rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Current file sequence # is: ',
              tape_descriptor^.next_position.file_sequence_number);
        rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
              $INTEGER (tape_descriptor^.labeled_volume_position));

        IF tape_descriptor^.labeled_volume_position <> bac$lvp_end_of_file_set THEN
          status.normal := TRUE;
          REPEAT
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_POSITION_AFTER_NEXT_EOF');
            sl_position_after_next_eof (file_identifier, status);
            IF status.normal THEN
              {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
              {                ^
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_READ_TAPE_LABELS');
              sl_read_tape_labels (file_identifier, ignore_label_group, status);
              {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
              {                           ^
              IF status.normal OR sl_irrelevant_condition (status) THEN
                sl_advance_tapemark (file_identifier, amc$forward, 1, status);
                {   *EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2 *
                {                                 ^
              ELSEIF status.condition = ame$unexpected_tapemark THEN
                sl_advance_tapemark (file_identifier, amc$backward, 1, ignore_status);
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to end of file set');
                tape_descriptor^.labeled_volume_position := bac$lvp_end_of_file_set;
                tape_descriptor^.volume_position := amc$after_tapemark;
                osp$set_status_condition (ame$file_not_in_volume_set, status);
                osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name,
                      status);
              IFEND;
            IFEND;
          UNTIL NOT status.normal;
        ELSE
          osp$set_status_condition (ame$file_not_in_volume_set, status);
          osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
        IFEND;

        IF status.condition = ame$file_not_in_volume_set THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Successfully positioned to EOS');
        IFEND;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting POSITION_TO_END_OF_SET');
        rmp$log_debug_status (status);

      PROCEND position_to_end_of_set;
?? OLDTITLE ??
?? NEWTITLE := '        position_to_file_identifier', EJECT ??

      PROCEDURE position_to_file_identifier
        (    file_identifier: amt$file_identifier;
             starting_point: 1 .. 9999;
             target_file_identifier: string (17);
             target_generation_number: 1 .. 9999;
         VAR status: ost$status);

{Design:  This procedure assumes that the volume must be searched in a forward
{direction from the current position.  It is not intended for random access, use
{sl_position_to_file_seq_no for this purpose.  If we encounter the end of the
{file set, the volume set is rewound and searching commences in the forward
{direction until we either find the target ANSI file or we are positioned back to
{the starting point.

        CONST
          la_fi = 1,
          la_gn = 2;

        VAR
          ignore_returned_attributes: fst$tla_returned_attributes,
          ignore_status: ost$status,
          last_accessed_attrib: ^array [1 .. 2] of fst$attachment_option,
          local_status: ost$status,
          rewound_volume_set: boolean,
          started_at_bos: boolean;

        status.normal := TRUE;
        rewound_volume_set := FALSE;
        started_at_bos := (tape_descriptor^.volume_number = 1) AND
              (tape_descriptor^.volume_position = amc$bov);
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_POSITION_TO_FILE_IDENTIFIER');
        rmp$log_debug_integer (target_file_identifier, target_generation_number);
        rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Will stop after FILE_SEQUENCE_NUMBER: ', starting_point);
        rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
              $INTEGER (tape_descriptor^.labeled_volume_position));
        REPEAT
          {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
          {                ^
          sl_find_next_header_group (file_identifier, status);
          {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
          {                           ^
          IF status.normal OR sl_irrelevant_condition (status) THEN
            PUSH last_accessed_attrib;
            last_accessed_attrib^ [la_fi].selector := fsc$tape_attachment;
            last_accessed_attrib^ [la_fi].tape_attachment.selector := fsc$tape_file_identifier;
            last_accessed_attrib^ [la_gn].selector := fsc$tape_attachment;
            last_accessed_attrib^ [la_gn].tape_attachment.selector := fsc$tape_generation_number;

            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FSP$GETTLA - last_accessed - Position FID');
            fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_last_ansi_file_accessed,
                  last_accessed_attrib^, ignore_returned_attributes, local_status);
            IF local_status.normal THEN
              IF (last_accessed_attrib^ [la_fi].tape_attachment.tape_file_identifier =
                    target_file_identifier) AND (last_accessed_attrib^ [la_gn].tape_attachment.
                    tape_generation_number = target_generation_number) THEN
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Found target file_identifier');
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting POSITION_TO_FILE_IDENTIFIER');
                RETURN; {----->
              ELSEIF (tape_descriptor^.next_position.file_sequence_number = starting_point) AND
                    (rewound_volume_set) THEN
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Went around the volume set');
                {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
                {                           ^
                sl_position_after_next_eof (file_identifier, ignore_status);
                {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2 * HDR1 etc.
                {                                              ^
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting POSITION_TO_FILE_IDENTIFIER');
                osp$set_status_condition (ame$file_not_in_volume_set, status);
                osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name,
                      status);
                RETURN; {----->
              IFEND;
            IFEND;
          ELSEIF (status.condition = ame$file_not_in_volume_set) AND (NOT rewound_volume_set) AND
                (NOT started_at_bos) THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Continuing FID search at BOS');
            rewind_tape (file_identifier, status);
            {   VOL1 HDR1 HDR2* data * EOF1 EOF2*
            {  ^
            rewound_volume_set := TRUE;
          IFEND;
          IF (NOT status.normal) AND sl_irrelevant_condition (status) THEN
            status.normal := TRUE;
          IFEND;
        UNTIL (NOT status.normal);
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Abnormal status terminated search');
        rmp$log_debug_status (status);
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting POSITION_TO_FILE_IDENTIFIER');
      PROCEND position_to_file_identifier;
?? OLDTITLE ??
?? EJECT ??

      CONST
        la_fi = 1,
        la_gn = 2;

      CONST
        np_fsp = 1,
        np_rl = 2;

      VAR
        file_set_position: fst$tape_file_set_position,
        ignore_returned_attributes: fst$tla_returned_attributes,
        ignore_status: ost$status,
        label_group: fst$ansi_label_kinds,
        last_accessed_attrib: ^array [la_fi .. la_gn] of fst$attachment_option,
        next_position_attrib: ^array [np_fsp .. np_rl] of fst$attachment_option;

      status.normal := TRUE;

      IF tape_descriptor^.initial_volume.header_labels = NIL THEN
        tape_descriptor^.next_position.file_section_number := 1;
        tape_descriptor^.next_position.file_sequence_number := 1;
      IFEND;
      PUSH next_position_attrib;
      next_position_attrib^ [np_fsp].selector := fsc$tape_attachment;
      next_position_attrib^ [np_fsp].tape_attachment.selector := fsc$tape_file_set_position;
      next_position_attrib^ [np_rl].selector := fsc$tape_attachment;
      next_position_attrib^ [np_rl].tape_attachment.selector := fsc$tape_rewrite_labels;

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering IMPLEMENT_FILE_SET_POSITION');
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FSP$GETTLA - next_position - Getting FSP');
      fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_next_position,
            next_position_attrib^, ignore_returned_attributes, status);
      IF status.normal THEN
        PUSH last_accessed_attrib;
        last_accessed_attrib^ [la_fi].selector := fsc$tape_attachment;
        last_accessed_attrib^ [la_fi].tape_attachment.selector := fsc$tape_file_identifier;
        last_accessed_attrib^ [la_gn].selector := fsc$tape_attachment;
        last_accessed_attrib^ [la_gn].tape_attachment.selector := fsc$tape_generation_number;

        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FSP$GETTLA - last_accessed - FSQP or FID');
        fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_last_ansi_file_accessed,
              last_accessed_attrib^, ignore_returned_attributes, status);
        IF status.normal THEN
          file_set_position := next_position_attrib^ [np_fsp].tape_attachment.tape_file_set_position;
          rewrite_labels := next_position_attrib^ [np_rl].tape_attachment.tape_rewrite_labels;
          IF tape_descriptor^.tape_attachment_information.volume_initialization THEN
            rewind_tape (file_identifier, ignore_status);
            IF rewrite_labels THEN
              sl_put_header_labels (file_identifier, {include_vol1_label=} TRUE, status);
            ELSE
              sl_read_tape_labels (file_identifier, label_group, status);
            IFEND;
            RETURN; {----->
          ELSEIF bap$next_position_is_bos (file_set_position, tape_descriptor,
                last_accessed_attrib^ [la_fi].tape_attachment.tape_file_identifier,
                last_accessed_attrib^ [la_gn].tape_attachment.tape_generation_number) THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Implementing FSP=BOS or equivalent');
            rewind_tape (file_identifier, status);
            IF status.normal THEN
              sl_read_tape_labels (file_identifier, label_group, status);
            IFEND;
          ELSEIF file_set_position.position = fsc$tape_current_file THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Implementing FSP=CURRENT_FILE');
            sl_rewind_ansi_file (file_identifier, status);
          ELSEIF file_set_position.position = fsc$tape_next_file THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Implementing FSP=NEXT_FILE');
            IF tape_descriptor^.rewind_file_command THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Implementing REWIND_FILE_COMMAND');
              sl_rewind_ansi_file (file_identifier, status);
            ELSE
              CASE tape_descriptor^.labeled_volume_position OF
              = bac$lvp_after_header_labels, bac$lvp_within_ansi_file =
                sl_position_after_next_eof (file_identifier, status);
              = bac$lvp_beginning_of_file_set, bac$lvp_after_trailer_labels =
                ;
              = bac$lvp_end_of_file_set, bac$lvp_end_of_volume_list =
                osp$set_status_condition (ame$file_not_in_volume_set, status);
                osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name,
                      status);
              ELSE
              CASEND;
              IF status.normal THEN
                sl_read_tape_labels (file_identifier, label_group, status);
                IF (NOT status.normal) AND (status.condition = ame$unexpected_tapemark) THEN
                  sl_advance_tapemark (file_identifier, amc$backward, 1, status);
                  rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to end of file set');
                  tape_descriptor^.labeled_volume_position := bac$lvp_end_of_file_set;
                  tape_descriptor^.volume_position := amc$after_tapemark;
                  osp$set_status_condition (ame$file_not_in_volume_set, status);
                  osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name,
                        status);
                IFEND;
              IFEND;
            IFEND;
          ELSEIF file_set_position.position = fsc$tape_end_of_set THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Implementing FSP=EOS');
            position_to_end_of_set (status);
          ELSE {file sequence position or file identifier position}
            rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
                  $INTEGER (tape_descriptor^.labeled_volume_position));
            rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Current file sequence # is: ',
                  tape_descriptor^.next_position.file_sequence_number);
            CASE file_set_position.position OF
            = fsc$tape_file_sequence_pos =
              rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Proposed file sequence # is: ',
                    file_set_position.file_sequence_number);
            = fsc$tape_file_identifier_pos =
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Last accessed FI: ');
              rmp$log_debug_message (last_accessed_attrib^ [la_fi].tape_attachment.tape_file_identifier);
              rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Last accessed GN: ',
                    last_accessed_attrib^ [la_gn].tape_attachment.tape_generation_number);
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Proposed FI: ');
              rmp$log_debug_message (file_set_position.file_identifier);
              rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Proposed GN: ',
                    file_set_position.generation_number);
            ELSE
            CASEND;

            IF sl_next_position_is_last_file (file_set_position, last_accessed_attrib^ [la_fi].
                  tape_attachment.tape_file_identifier, last_accessed_attrib^ [la_gn].tape_attachment.
                  tape_generation_number) THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Rewinding last ANSI file');
              sl_rewind_ansi_file (file_identifier, status);
            ELSEIF file_set_position.position = fsc$tape_file_sequence_pos THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Implementing FSP=FSP or equivalent');
              sl_position_to_file_seq_number (file_identifier, file_set_position.file_sequence_number,
                    status);
            ELSEIF file_set_position.position = fsc$tape_file_identifier_pos THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Implementing FSP=FIP or equivalent');
              IF bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
                position_to_file_identifier (file_identifier, tape_descriptor^.next_position.
                      file_sequence_number - 1, file_set_position.file_identifier,
                      file_set_position.generation_number, status);
              ELSE
                position_to_file_identifier (file_identifier, tape_descriptor^.next_position.
                      file_sequence_number, file_set_position.file_identifier,
                      file_set_position.generation_number, status);
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;

      IF (NOT status.normal) AND (status.condition = ame$file_not_in_volume_set) THEN
        CASE file_set_position.position OF
        = fsc$tape_beginning_of_set =
          IF state_info^.file_access = bac$write {implies shorten allowed} THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting REWRITE_LABELS to TRUE');
            rewrite_labels := TRUE;
            status.normal := TRUE;
          IFEND;
        = fsc$tape_end_of_set, fsc$tape_next_file =
          CASE state_info^.file_access OF
          = bac$write, bac$append =
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting REWRITE_LABELS to TRUE');
            rewrite_labels := TRUE;
            status.normal := TRUE;
          ELSE
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Not bac$write nor bac$append');
          CASEND;
        = fsc$tape_file_sequence_pos =
          IF file_set_position.file_sequence_number = tape_descriptor^.next_position.file_sequence_number THEN
            CASE state_info^.file_access OF
            = bac$write, bac$append =
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting REWRITE_LABELS to TRUE');
              rewrite_labels := TRUE;
              status.normal := TRUE;
            ELSE
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Neither bac$write nor bac$append');
            CASEND;
          ELSE
            osp$set_status_condition (ame$spec_fsn_out_of_seq, status);
            osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
          IFEND;
        ELSE
        CASEND;
      IFEND;
      IF status.normal THEN
        IF (tape_descriptor^.volume_number = 1) AND (((tape_descriptor^.next_position.file_sequence_number =
              1) AND (tape_descriptor^.labeled_volume_position = bac$lvp_after_header_labels)) OR
              ((tape_descriptor^.next_position.file_sequence_number = 2) AND
              bap$after_trailer_labels (tape_descriptor^.labeled_volume_position))) THEN

          IF (tape_descriptor^.initial_volume.classification.volume_label_type = rmc$labeled_volume_type) AND
                (state_info^.file_access = bac$write) THEN
            {May set REWRITE_LABELS to TRUE and rewind the tape, if pre-L780 blank labeled}
            adjust_rewrite_labels (rewrite_labels);
          IFEND;

          IF tape_descriptor^.initial_volume.classification.labeled.blank THEN
            rewind_tape (file_identifier, ignore_status);
            CASE state_info^.file_access OF
            = bac$write =
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Forcing REWRITE_LABELS to TRUE');
              rewrite_labels := TRUE;
            = bac$append =
              IF (pfc$append IN file_instance^.instance_attributes.dynamic_label.access_mode) THEN
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Forcing REWRITE_LABELS to TRUE');
                rewrite_labels := TRUE;
              ELSE
                osp$set_status_condition (ame$blank_volume_read, status);
                osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name,
                      status);
                osp$append_status_parameter (osc$status_parameter_delimiter,
                      tape_descriptor^.initial_volume.classification.labeled.volume_identifier, status);
              IFEND;
            = bac$read =
              osp$set_status_condition (ame$blank_volume_read, status);
              osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
              osp$append_status_parameter (osc$status_parameter_delimiter,
                    tape_descriptor^.initial_volume.classification.labeled.volume_identifier, status);
            ELSE
            CASEND;
          IFEND;
        IFEND;
      IFEND;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting IMPLEMENT_FILE_SET_POSITION');

    PROCEND implement_file_set_position;
?? OLDTITLE ??
?? NEWTITLE := '      implement_open_position', EJECT ??

    PROCEDURE implement_open_position
      (    rewrite_labels: boolean;
       VAR status: ost$status);

      status.normal := TRUE;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering IMPLEMENT_OPEN_POSITION');
      rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
            $INTEGER (tape_descriptor^.labeled_volume_position));
      CASE state_info^.file_access OF
      = bac$write =
        IF rewrite_labels THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: bac$write and REWRITE_LABELS=TRUE');
          {
          {  EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
          {                        ^
          CASE tape_descriptor^.labeled_volume_position OF
          = bac$lvp_beginning_of_file_set =
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Writing File Header Labels at BOS');
            sl_put_header_labels (file_identifier, {include_vol1_label=} TRUE, status);
          = bac$lvp_after_trailer_labels, bac$lvp_end_of_file_set =
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Writing File Header Labels at EOS');
            sl_put_header_labels (file_identifier, {include_vol1_label=} FALSE, status);
          = bac$lvp_after_header_labels, bac$lvp_within_ansi_file =
            sl_advance_tapemark (file_identifier, amc$backward, 2, status);
            IF status.normal THEN
              {
              {  EOF1 EOF2 * HDR1 HDR2* data *EOF1 EOF2*
              {           ^
              sl_advance_tapemark (file_identifier, amc$forward, 1, status);
              IF status.normal THEN
                {
                {  EOF1 EOF2 * HDR1 HDR2* data *EOF1 EOF2*
                {             ^
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Rewriting File Header Labels');
                tape_descriptor^.labeled_volume_position := bac$lvp_before_header_labels;
                sl_put_header_labels (file_identifier, {include_vol1_label=} FALSE, status);
              IFEND;
            ELSEIF status.condition = ame$skip_encountered_bov THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Rewriting Volume Header Labels');
              IF tape_descriptor^.volume_number = 1 THEN
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Reset NEXT_POSITION to 1 at BOS');
                tape_descriptor^.labeled_volume_position := bac$lvp_beginning_of_file_set;
                tape_descriptor^.next_position.file_section_number := 1;
                tape_descriptor^.next_position.file_sequence_number := 1;
              IFEND;
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Writing File Header Labels at BOV');
              sl_put_header_labels (file_identifier, {include_vol1_label=} TRUE, status);
            IFEND;
          = bac$lvp_end_of_volume_list =
            amp$set_file_instance_abnormal (file_identifier, ame$tape_end_of_volume_list, operation, '',
                  status);
          CASEND;
        IFEND;
        {
        {  EOF1  EOF2*HDR1 HDR2* data *EOF1 EOF2*
        {                       ^
      = bac$append = {Implies either $EOI, only append access, or both $EOI and append access}
        rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Open Position is: ',
              $INTEGER (file_instance^.instance_attributes.dynamic_label.open_position));
        CASE tape_descriptor^.labeled_volume_position OF
        = bac$lvp_beginning_of_file_set = {Volume must be blank}
          sl_put_header_labels (file_identifier, {include_volume_label} TRUE, status);
        = bac$lvp_end_of_volume_list =
          amp$set_file_instance_abnormal (file_identifier, ame$tape_end_of_volume_list, operation, '',
                status);
        = bac$lvp_end_of_file_set =
          IF pfc$append IN file_instance^.instance_attributes.dynamic_label.access_mode THEN
            sl_put_header_labels (file_identifier, {include_volume_label=} FALSE, status);
          IFEND;
        ELSE
          IF rewrite_labels AND (file_instance^.instance_attributes.dynamic_label.open_position <>
                amc$open_at_eoi) THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: bac$append and rewrite_labels');
            sl_put_header_labels (file_identifier, {include_volume_label=} FALSE, status);
          ELSE
            IF NOT bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: bac$append and/or $EOI');
              sl_position_after_next_eof (file_identifier, status);
              {
              {  EOF1  EOF2*HDR1 HDR2* data *EOF1 EOF2*
              {                                        ^
            IFEND;
            IF status.normal THEN
              sl_reposition_for_put_at_eoi (file_identifier, status);
              {
              {  EOF1  EOF2*HDR1 HDR2* data *EOF1 EOF2*
              {                            ^
            IFEND;
          IFEND;
        CASEND;
      ELSE { state_info^.file_access = bac$read }
      CASEND;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting IMPLEMENT_OPEN_POSITION');
    PROCEND implement_open_position;
?? OLDTITLE ??
?? EJECT ??

    VAR
      rewrite_labels: boolean;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_OPEN_LABEL_FILE');
    implement_file_set_position (rewrite_labels, status);
    IF status.normal AND (NOT tape_descriptor^.tape_attachment_information.volume_initialization) THEN
      implement_open_position (rewrite_labels, status);
      IF status.normal THEN
        adjust_file_attributes (status);
      IFEND;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_OPEN_LABEL_FILE');

  PROCEND sl_open_label_file;
?? OLDTITLE ??
?? NEWTITLE := '    sl_position_after_next_eof', EJECT ??

  PROCEDURE sl_position_after_next_eof
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

{Design: On entry, the tape could be positioned just about anywhere, including the
{end of the volume set.  We advance volumes, if necessary, to find the next EOF.
{

    VAR
      label_group: fst$ansi_label_kinds;

    {   * EOF1 EOF2* HDR1 HDR2* data * EOF1 EOF2* * *
    {               ?             ?              ?
    status.normal := TRUE;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_POSITION_AFTER_NEXT_EOF');
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));

    REPEAT
      sl_find_next_trailer_group (file_identifier, label_group, status);
      IF status.normal THEN
        IF fsp$file_trailer_labels (label_group) THEN
          state_info^.put_op := FALSE;
          file_instance^.previous_get_at_eoi := FALSE;
          {   * EOF1 EOF2* HDR1 HDR2* data * EOF1 EOF2* HDR1 HDR2
          {                                            ^
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_POSITION_AFTER_NEXT_EOF - success');
          RETURN; {----->
        ELSEIF fsp$volume_trailer_labels (label_group) THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Read volume trailer labels');
          sl_advance_volume (file_identifier, status);
          {   VOL1 HDR1 HDR2* data * EOF1 EOF2*
          {  ^
        IFEND;
      IFEND;
    UNTIL NOT status.normal;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_POSITION_AFTER_NEXT_EOF - abnormal status');
    rmp$log_debug_status (status);

  PROCEND sl_position_after_next_eof;
?? OLDTITLE ??
?? NEWTITLE := '    sl_position_to_file_seq_number', EJECT ??

  PROCEDURE sl_position_to_file_seq_number
    (    file_identifier: amt$file_identifier;
         target_file_seq_number: 1 .. 9999;
     VAR status: ost$status);

    status.normal := TRUE;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_POSITION_TO_FILE_SEQ_NUMBER');
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Positioning to file sequence #', target_file_seq_number);
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));
    IF target_file_seq_number < tape_descriptor^.next_position.file_sequence_number THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Rewinding volume set');
      rewind_tape (file_identifier, status);
      {   VOL1 HDR1 HDR2* data * EOF1 EOF2*
      {  ^
    IFEND;

    IF status.normal THEN
      IF target_file_seq_number < tape_descriptor^.next_position.file_sequence_number THEN
        {The value in the first HDR1 label of the file set is greater than the request}
        osp$set_status_condition (ame$fsn_out_of_sequence, status);
        osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
      ELSE
        REPEAT
          sl_find_next_header_group (file_identifier, status);
          {   * EOF1 EOF2 * HDR1 HDR2 * data * EOF1 EOF2*
          {                          ^
        UNTIL (target_file_seq_number = tape_descriptor^.next_position.file_sequence_number) OR
              ((NOT status.normal) AND (NOT sl_irrelevant_condition (status)));
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_POSITION_TO_FILE_SEQ_NUMBER');
        rmp$log_debug_status (status);
      IFEND;
    IFEND;
  PROCEND sl_position_to_file_seq_number;
?? OLDTITLE ??
?? NEWTITLE := '    sl_preauthorize_access_method', EJECT ??

  PROCEDURE sl_preauthorize_access_method
    (    file_identifier: amt$file_identifier;
         access_method: amt$file_label_type;
     VAR status: ost$status);

    VAR
      tape_security_call_block: fst$tape_security_call_block;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_PREAUTHORIZE_ACCESS_METHOD');
    tape_security_call_block.operation := fsc$ts_authorize_access_method;
    tape_security_call_block.authorize_access_method.access_method := access_method;
    sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
    IF NOT status.normal THEN
      rmp$log_debug_status (status);
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_PREAUTHORIZE_ACCESS_METHOD');

  PROCEND sl_preauthorize_access_method;
?? OLDTITLE ??
?? NEWTITLE := '    sl_put_end_of_file_labels', EJECT ??

  PROCEDURE sl_put_end_of_file_labels
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      attachment_options: ^array [1 .. 1] of fst$attachment_option,
      block_count: 0 .. 999999,
      ignore_returned_attributes: fst$tla_returned_attributes,
      trailer_labels: ^SEQ (REP 1 of fst$tape_label_sequence_header, REP 4 of fst$tape_label_block_descriptor,
            {tapemark} REP 1 of fst$ansi_eof1_label, REP 1 of fst$ansi_eof2_label {tapemark} );

    status.normal := TRUE;
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));
    flush_req (file_identifier, status);
    IF status.normal THEN
      PUSH trailer_labels;
      PUSH attachment_options;
      attachment_options^ [1].selector := fsc$tape_attachment;
      attachment_options^ [1].tape_attachment.selector := fsc$tape_trailer_labels;
      attachment_options^ [1].tape_attachment.tape_trailer_labels := trailer_labels;

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FSP$GETTLA - next_position - Getting TRL');
      fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_next_position,
            attachment_options^, ignore_returned_attributes, status);
      IF status.normal THEN
        sl_adjust_trailer_labels (file_identifier, trailer_labels, fsc$ansi_eof_label_identifier, status);
        IF status.normal THEN
          sl_put_trailer_labels (file_identifier, trailer_labels, status);
          IF status.normal THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to end of file set');
            tape_descriptor^.labeled_volume_position := bac$lvp_end_of_file_set;
            file_instance^.previous_get_at_eoi := FALSE;
            tape_descriptor^.next_position.file_section_number := 1;
            sl_increment_file_sequence_no;
          IFEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND sl_put_end_of_file_labels;
?? OLDTITLE ??
?? NEWTITLE := '    sl_put_end_of_vol_labels', EJECT ??

  PROCEDURE sl_put_end_of_vol_labels
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    VAR
      attachment_options: ^array [1 .. 1] of fst$attachment_option,
      block_count: 0 .. 999999,
      ignore_returned_attributes: fst$tla_returned_attributes,
      trailer_labels: ^SEQ (REP 1 of fst$tape_label_sequence_header, REP 4 of fst$tape_label_block_descriptor,
            {tapemark} REP 1 of fst$ansi_eof1_label, REP 1 of fst$ansi_eof2_label {tapemark} );

    status.normal := TRUE;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_PUT_END_OF_VOL_LABELS');
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));
    PUSH trailer_labels;
    PUSH attachment_options;
    attachment_options^ [1].selector := fsc$tape_attachment;
    attachment_options^ [1].tape_attachment.selector := fsc$tape_trailer_labels;
    attachment_options^ [1].tape_attachment.tape_trailer_labels := trailer_labels;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FSP$GETTLA - next_position - Getting TRL');
    fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_next_position, attachment_options^,
          ignore_returned_attributes, status);
    IF status.normal THEN
      sl_adjust_trailer_labels (file_identifier, trailer_labels, fsc$ansi_eov_label_identifier, status);
      IF status.normal THEN
        sl_put_trailer_labels (file_identifier, trailer_labels, status);
        IF status.normal THEN
          rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SECTION_NUMBER was: ',
                tape_descriptor^.next_position.file_section_number);
          tape_descriptor^.next_position.file_section_number :=
                tape_descriptor^.next_position.file_section_number + 1;
          rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SECTION_NUMBER incremented to: ',
                tape_descriptor^.next_position.file_section_number);
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to after trailer labels');
          tape_descriptor^.labeled_volume_position := bac$lvp_after_trailer_labels;
        IFEND;
      IFEND;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_PUT_END_OF_VOL_LABELS');

  PROCEND sl_put_end_of_vol_labels;
?? OLDTITLE ??
?? NEWTITLE := '    sl_put_header_labels', EJECT ??

  PROCEDURE sl_put_header_labels
    (    file_identifier: amt$file_identifier;
         include_vol1_label: boolean;
     VAR status: ost$status);

    CONST
      hl = 1;

    VAR
      attachment_options: ^array [hl .. hl] of fst$attachment_option,
      call_block: amt$call_block,
      ignore_returned_attributes: fst$tla_returned_attributes,
      header_labels: ^SEQ (REP 1 of fst$tape_label_sequence_header, REP 4 of fst$tape_label_block_descriptor,
            REP 1 of fst$ansi_vol1_label, REP 1 of fst$ansi_hdr1_label, REP 1 of fst$ansi_hdr2_label)
            {tapemark} ,
      label_identifier: fst$tape_label_identifier,
      label_locator: fst$tape_label_locator,
      secured_sequence: ^SEQ ( * ),
      sequence_header: ^fst$tape_label_sequence_header,
      tape_security_call_block: fst$tape_security_call_block,
      unsecured_sequence: ^SEQ ( * );

    status.normal := TRUE;
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));

    IF tape_descriptor^.tape_attachment_information.volume_initialization THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_AUTHORIZE_WRITE_ACCESS');
      sl_authorize_write_access (file_identifier, tape_descriptor^.tape_attachment_information.
            tape_volume_initialization.blank_label_group, include_vol1_label, status);
    ELSE
      PUSH header_labels;

      PUSH attachment_options;
      attachment_options^ [hl].selector := fsc$tape_attachment;
      attachment_options^ [hl].tape_attachment.selector := fsc$tape_header_labels;
      attachment_options^ [hl].tape_attachment.tape_header_labels := header_labels;

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FSP$GETTLA - next_position - Getting HDRL');
      fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_next_position,
            attachment_options^, ignore_returned_attributes, status);
      IF status.normal THEN
        RESET header_labels;
        IF NOT include_vol1_label THEN
          NEXT sequence_header IN header_labels;
          IF sequence_header <> NIL THEN
            sequence_header^.label_kinds := sequence_header^.label_kinds -
                  $fst$ansi_label_kinds [fsc$ansi_vol1_label_kind];
          IFEND;
          label_identifier.location_method := fsc$tape_label_locate_by_kind;
          label_identifier.label_kind := fsc$ansi_vol1_label_kind;
          fsp$locate_tape_label (header_labels, label_identifier, label_locator);

          IF label_locator.label_found THEN
            label_locator.label_block_descriptor^.label_block_type := fsc$null_tape_label_block;
          IFEND;
        IFEND;
        IF include_vol1_label OR (tape_descriptor^.labeled_volume_position = bac$lvp_before_header_labels)
              THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_AUTHORIZE_WRITE_ACCESS');
          sl_authorize_write_access (file_identifier, header_labels, include_vol1_label, status);
        IFEND;
        IF status.normal THEN
          call_block.operation := amc$write_tape_labels;
          call_block.write_tape_labels := header_labels;
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to write header labels');
          amp$access_method (file_identifier, call_block, global_layer_number, status);
        IFEND;
      IFEND;

      IF status.normal THEN
        bov_position := FALSE;
        state_info^.eoi_labels_needed := TRUE;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to after header labels');
        tape_descriptor^.labeled_volume_position := bac$lvp_after_header_labels;
        tape_descriptor^.volume_position := amc$after_tapemark;

        unsecured_sequence := tape_descriptor^.last_accessed.unsecured_header_labels;
        IF unsecured_sequence <> NIL THEN
          RESET unsecured_sequence;
          NEXT sequence_header IN unsecured_sequence;
          IF sequence_header <> NIL THEN
            PUSH secured_sequence: [[REP sequence_header^.sequence_size OF cell]];
            RESET secured_sequence;
            RESET unsecured_sequence;
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Making working copy of secured labels');
            secured_sequence^ := unsecured_sequence^;
            tape_security_call_block.operation := fsc$ts_secure_header_labels;
            tape_security_call_block.secure_header_labels.header_labels := secured_sequence;
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to secure header labels');
            sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
            IF status.normal THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing secured header labels');
              tape_descriptor^.last_accessed.secured_header_labels^ := secured_sequence^;
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting AT_EOI to TRUE; blank volume append');
              tape_descriptor^.at_eoi := TRUE;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND sl_put_header_labels;
?? OLDTITLE ??
?? NEWTITLE := '    sl_put_trailer_labels', EJECT ??

  PROCEDURE sl_put_trailer_labels
    (    file_identifier: amt$file_identifier;
         label_sequence: ^SEQ ( * );
     VAR status: ost$status);

    VAR
      call_block: amt$call_block,
      ignore_status: ost$status,
      secured_sequence: ^SEQ ( * ),
      sequence_header: ^fst$tape_label_sequence_header,
      tape_failure_modes: amt$tape_failure_modes,
      tape_security_call_block: fst$tape_security_call_block,
      trailer_labels: ^SEQ ( * ),
      unsecured_sequence: ^SEQ ( * );

    status.normal := TRUE;
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));
    trailer_labels := label_sequence;
    RESET trailer_labels;
    call_block.operation := amc$write_tape_labels;
    call_block.write_tape_labels := trailer_labels;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to write trailer labels');
    amp$access_method (file_identifier, call_block, global_layer_number, status);

    IF status.normal THEN
      bap$tape_bm_write_label_mark (file_identifier, {system_media_recovery=} TRUE, tape_failure_modes,
            status);
      IF status.normal THEN
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Wrote 2ND tapemark');
        bap$tape_bm_write_label_mark (file_identifier, {system_media_recovery=} TRUE, tape_failure_modes,
              status);
        IF status.normal THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Wrote 3RD tapemark');
          sl_advance_tapemark (file_identifier, amc$backward, 2, ignore_status);
        ELSE
          sl_advance_tapemark (file_identifier, amc$backward, 1, ignore_status);
          tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
          tape_descriptor^.failure_isolation.failed_at_current_position := TRUE;
        IFEND;
      ELSE
        tape_descriptor^.failure_isolation.failure_modes := tape_failure_modes;
        tape_descriptor^.failure_isolation.failed_at_current_position := TRUE;
      IFEND;
      tape_descriptor^.volume_position := amc$after_tapemark;
    IFEND;
    state_info^.eoi_labels_needed := FALSE;

    unsecured_sequence := tape_descriptor^.last_accessed.unsecured_trailer_labels;
    RESET unsecured_sequence;
    NEXT sequence_header IN unsecured_sequence;
    IF sequence_header <> NIL THEN
      PUSH secured_sequence: [[REP sequence_header^.sequence_size OF cell]];
      RESET secured_sequence;
      RESET unsecured_sequence;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Making working copy of secured labels');
      secured_sequence^ := unsecured_sequence^;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to secure trailer labels');
      tape_security_call_block.operation := fsc$ts_secure_trailer_labels;
      tape_security_call_block.secure_trailer_labels.trailer_labels := secured_sequence;
      sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
      IF status.normal THEN
        tape_descriptor^.last_accessed.secured_trailer_labels^ := secured_sequence^;
      IFEND;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting AT_EOI to TRUE');
    tape_descriptor^.at_eoi := TRUE;

  PROCEND sl_put_trailer_labels;
?? OLDTITLE ??
?? NEWTITLE := '    sl_read_tape_labels', EJECT ??

  PROCEDURE sl_read_tape_labels
    (    file_identifier: amt$file_identifier;
     VAR label_group: fst$ansi_label_kinds;
     VAR status: ost$status);

    CONST
      bc = 1;

?? NEWTITLE := '      process_header_labels ', EJECT ??

    PROCEDURE process_header_labels;

?? NEWTITLE := '        initialize_next_position' ??

      PROCEDURE initialize_next_position
        (    header_labels: ^SEQ ( * ));

{Design: The purpose of this procedure is to support a user who mounts a subset of
{a volume set omitting the first volume of the set.  A warning message is logged and
{the FILE_SECTION_NUMBER and FILE_SEQUENCE_NUMBER are initialized from the first
{volume of the subset.  This requires a user who positions by FILE_SEQUENCE_NUMBER
{to use values originally written with the volume set, i.e. the first file of the
{subset may have a file sequence number > 1.

        VAR
          file_section_no: clt$integer,
          file_section_number: 1 .. 9999,
          file_sequence_no: clt$integer,
          file_sequence_number: 1 .. 9999,
          hdr1_label: ^fst$ansi_hdr1_label,
          ignore_status: ost$status,
          label_identifier: fst$tape_label_identifier,
          label_locator: fst$tape_label_locator,
          local_status: ost$status,
          vol1_label: ^fst$ansi_vol1_label;

        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering INITIALIZE_NEXT_POSITION');

        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Volume 1 - setting FSEC&FSEQ to 1');
        tape_descriptor^.next_position.file_section_number := 1;
        tape_descriptor^.next_position.file_sequence_number := 1;

        label_identifier.location_method := fsc$tape_label_locate_by_kind;
        label_identifier.label_kind := fsc$ansi_vol1_label_kind;
        fsp$locate_tape_label (header_labels, label_identifier, label_locator);
        IF label_locator.label_found THEN
          RESET label_locator.label_block;
          NEXT vol1_label IN label_locator.label_block;
          label_identifier.label_kind := fsc$ansi_hdr1_label_kind;
          fsp$locate_tape_label (header_labels, label_identifier, label_locator);
          IF (vol1_label <> NIL) AND label_locator.label_found THEN
            RESET label_locator.label_block;
            NEXT hdr1_label IN label_locator.label_block;
            IF (hdr1_label <> NIL) THEN
              file_sequence_number := 1;
              IF (hdr1_label^.file_sequence_number <> ' ') THEN
                clp$convert_string_to_integer (hdr1_label^.file_sequence_number, file_sequence_no,
                      local_status);
                IF local_status.normal AND (file_sequence_no.value > 1) AND
                      (file_sequence_no.value <= 9999) THEN
                  file_sequence_number := file_sequence_no.value;
                IFEND;
              IFEND;
              file_section_number := 1;
              IF (hdr1_label^.file_section_number <> ' ') THEN
                clp$convert_string_to_integer (hdr1_label^.file_section_number, file_section_no,
                      local_status);
                IF local_status.normal AND (file_section_no.value > 1) AND
                      (file_section_no.value <= 9999) THEN
                  file_section_number := file_section_no.value;
                IFEND
              IFEND;
              IF (file_sequence_number > 1) OR (file_section_number > 1) THEN
                IF ((pfc$read IN file_instance^.instance_attributes.dynamic_label.access_mode) AND
                      (file_section_number > 1)) THEN
                  osp$set_status_condition (ame$not_initial_volume_of_set, local_status);
                  osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name,
                        local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, vol1_label^.volume_identifier,
                        local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter, hdr1_label^.file_identifier,
                        local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        hdr1_label^.file_section_number, local_status);
                  osp$append_status_parameter (osc$status_parameter_delimiter,
                        hdr1_label^.file_sequence_number, local_status);
                  osp$generate_log_message ($pmt$ascii_logset [pmc$job_log], local_status, ignore_status);
                IFEND;
              IFEND;
              IF file_sequence_number > 1 THEN
                rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Setting FILE_SEQUENCE_NUMBER from HDR1 label: ',
                      file_sequence_number);
                tape_descriptor^.next_position.file_sequence_number := file_sequence_number;
              IFEND;
              IF file_section_number > 1 THEN
                rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Setting FILE_SECTION_NUMBER from HDR1 label: ',
                      file_section_number);
                tape_descriptor^.next_position.file_section_number := file_section_number;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting INITIALIZE_NEXT_POSITION');
      PROCEND initialize_next_position;
?? OLDTITLE, EJECT ??

      VAR
        call_block: amt$call_block,
        secured_sequence: ^SEQ ( * ),
        sequence_header: ^fst$tape_label_sequence_header,
        tape_security_call_block: fst$tape_security_call_block,
        unsecured_sequence: ^SEQ ( * );

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering PROCESS_HEADER_LABELS');
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to after header labels');
      tape_descriptor^.labeled_volume_position := bac$lvp_after_header_labels;
      unsecured_sequence := tape_descriptor^.last_accessed.unsecured_header_labels;
      IF unsecured_sequence <> NIL THEN
        RESET unsecured_sequence;
        NEXT sequence_header IN unsecured_sequence;
        IF sequence_header <> NIL THEN
          PUSH secured_sequence: [[REP sequence_header^.sequence_size OF cell]];
          RESET secured_sequence;
          RESET unsecured_sequence;
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Making working copy of secured labels');
          secured_sequence^ := unsecured_sequence^;
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to validate header labels');
          tape_security_call_block.operation := fsc$ts_validate_header_labels;
          tape_security_call_block.validate_header_labels.header_labels := secured_sequence;
          sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
          IF status.normal THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Successfully validated header labels');
            rmp$log_debug_message (
                  'LABELED_TAPE_DEBUG: Calling bap$store_unsecured_tape_labels for header labels');
            bap$store_unsecured_tape_labels (secured_sequence,
                  tape_descriptor^.last_accessed.unsecured_header_labels);
            tape_security_call_block.operation := fsc$ts_secure_header_labels;
            tape_security_call_block.secure_header_labels.header_labels := secured_sequence;
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to secure header labels');
            sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
            IF status.normal THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Moving secured header labels to tape_descriptor');
              tape_descriptor^.last_accessed.secured_header_labels^ := secured_sequence^;
              IF fsp$volume_header_labels (label_group) AND (tape_descriptor^.volume_number = 1) THEN
                initialize_next_position (secured_sequence);
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting PROCESS_HEADER_LABELS');
    PROCEND process_header_labels;
?? OLDTITLE ??
?? NEWTITLE := '      process_trailer_labels ', EJECT ??

    PROCEDURE process_trailer_labels;

      CONST
        read_mode = 'READ';

      VAR
        ansi_file_attrib: ^array [1 .. 1] of fst$attachment_option,
        call_block: amt$call_block,
        ignore_returned_attributes: fst$tla_returned_attributes,
        secured_sequence: ^SEQ ( * ),
        sequence_header: ^fst$tape_label_sequence_header,
        tape_security_call_block: fst$tape_security_call_block,
        unsecured_sequence: ^SEQ ( * );

      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering PROCESS_TRAILER_LABELS');
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to after trailer labels');
      tape_descriptor^.labeled_volume_position := bac$lvp_after_trailer_labels;
      unsecured_sequence := tape_descriptor^.last_accessed.unsecured_trailer_labels;
      RESET unsecured_sequence;
      NEXT sequence_header IN unsecured_sequence;
      IF sequence_header <> NIL THEN
        PUSH secured_sequence: [[REP sequence_header^.sequence_size OF cell]];
        RESET secured_sequence;
        RESET unsecured_sequence;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Making working copy of secured labels');
        secured_sequence^ := unsecured_sequence^;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to validate trailer labels');
        tape_security_call_block.operation := fsc$ts_validate_trailer_labels;
        tape_security_call_block.validate_trailer_labels.trailer_labels := secured_sequence;
        sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
        IF status.normal THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Successfully validated trailer labels');
          rmp$log_debug_message (
                'LABELED_TAPE_DEBUG: Calling bap$store_unsecured_tape_labels for trailer labels');
          bap$store_unsecured_tape_labels (secured_sequence,
                tape_descriptor^.last_accessed.unsecured_trailer_labels);
          tape_security_call_block.operation := fsc$ts_secure_trailer_labels;
          tape_security_call_block.secure_trailer_labels.trailer_labels := secured_sequence;
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to secure trailer labels');
          sl_enforce_tape_security (file_identifier, tape_security_call_block, status);
          IF status.normal THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Moving secured trailer labels to tape_descriptor');
            tape_descriptor^.last_accessed.secured_trailer_labels^ := secured_sequence^;
            PUSH ansi_file_attrib;
            ansi_file_attrib^ [bc].selector := fsc$tape_attachment;
            ansi_file_attrib^ [bc].tape_attachment.selector := fsc$tape_block_count;

            fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_last_ansi_file_accessed,
                  ansi_file_attrib^, ignore_returned_attributes, status);

            IF status.normal THEN
              state_info^.eof1_block_count := ansi_file_attrib^ [bc].tape_attachment.tape_block_count;
              IF fsp$file_trailer_labels (label_group) THEN
                IF state_info^.file_access <> bac$append THEN
                  tape_descriptor^.next_position.file_section_number := 1;
                IFEND;
                sl_log_eof_block_count (ansi_file_attrib^ [bc].tape_attachment.tape_block_count, read_mode);
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Incrementing FILE_SEQUENCE_NUMBER');
                sl_increment_file_sequence_no;
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting AT_EOI to TRUE');
                tape_descriptor^.at_eoi := TRUE;
              ELSEIF fsp$volume_trailer_labels (label_group) THEN
                rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SECTION_NUMBER was: ',
                      tape_descriptor^.next_position.file_section_number);
                sl_log_eov_block_count (ansi_file_attrib^ [bc].tape_attachment.tape_block_count, read_mode);
                tape_descriptor^.next_position.file_section_number :=
                      tape_descriptor^.next_position.file_section_number + 1;
                rmp$log_debug_integer ('LABELED_TAPE_DEBUG: FILE_SECTION_NUMBER incremented to: ',
                      tape_descriptor^.next_position.file_section_number);
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to after trailer labels');
                tape_descriptor^.labeled_volume_position := bac$lvp_after_trailer_labels;
              IFEND;
            IFEND;
          IFEND;
        IFEND;
      IFEND;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting PROCESS_TRAILER_LABELS');
    PROCEND process_trailer_labels;
?? OLDTITLE, EJECT ??

    VAR
      call_block: amt$call_block,
      initial_volume_position: amt$volume_position,
      read_labels_status: ost$status,
      read_tape_labels: amt$read_tape_labels;

    status.normal := TRUE;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_READ_TAPE_LABELS');
    initial_volume_position := tape_descriptor^.volume_position;

    call_block.operation := amc$read_tape_labels;
    call_block.read_tape_labels := ^read_tape_labels;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling FAP to read labels');
    amp$access_method (file_identifier, call_block, global_layer_number, read_labels_status);

    IF read_labels_status.normal THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Successfully read labels');
      label_group := read_tape_labels.label_kinds;
      IF fsp$header_labels (label_group) THEN
        process_header_labels;
        IF status.normal THEN
          IF (NOT tape_descriptor^.tape_attachment_information.volume_initialization) THEN
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_AUTHORIZE_ACCESS - normal');
            sl_authorize_access (file_identifier, label_group, read_labels_status, status);
          IFEND;
        IFEND;
      ELSEIF fsp$trailer_labels (label_group) THEN
        process_trailer_labels;
      IFEND;
    ELSE
      status := read_labels_status;
      CASE read_labels_status.condition OF
      = ame$invalid_tape_label, ame$unexpected_tapemark =
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to within ANSI file');
        tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
      ELSE
      CASEND;
      IF NOT tape_descriptor^.tape_attachment_information.volume_initialization THEN
        IF tape_descriptor^.initial_volume.initial_read_labels_attempt AND
              (initial_volume_position = amc$bov) THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling SL_AUTHORIZE_ACCESS - abnormal');
          status.normal := TRUE;
          sl_authorize_access (file_identifier, $fst$ansi_label_kinds [], read_labels_status, status);
          tape_descriptor^.initial_volume.initial_read_labels_attempt := NOT status.normal;
        IFEND;
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Failed to read labels');
      IFEND;
    IFEND;
    rmp$log_debug_status (status);
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_READ_TAPE_LABELS');
  PROCEND sl_read_tape_labels;
?? OLDTITLE ??
?? NEWTITLE := '    sl_reposition_for_put_at_eoi', EJECT ??

  PROCEDURE sl_reposition_for_put_at_eoi
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

    status.normal := TRUE;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_REPOSITION_FOR_PUT_AT_EOI');
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));
    sl_advance_tapemark (file_identifier, amc$backward, 2, status);
    IF status.normal THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to within ANSI file');
      tape_descriptor^.labeled_volume_position := bac$lvp_within_ansi_file;
      IF state_info^.eof1_block_count = 0 THEN
        gfi^.positioning_info.block_info.block_number := 1;
        bov_position := FALSE;
        tape_descriptor^.volume_position := amc$before_tapemark;
      ELSE
        gfi^.positioning_info.block_info.block_number := state_info^.eof1_block_count;
        bov_position := FALSE;
        tape_descriptor^.volume_position := amc$after_data_block;
      IFEND;
      gfi^.positioning_info.record_info.file_position := amc$eoi;
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting AT_EOI to TRUE');
      tape_descriptor^.at_eoi := TRUE;
      sl_decrement_file_sequence_no;
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_REPOSITION_FOR_PUT_AT_EOI');

  PROCEND sl_reposition_for_put_at_eoi;
?? OLDTITLE ??
?? NEWTITLE := '    sl_rewind_ansi_file', EJECT ??

  PROCEDURE sl_rewind_ansi_file
    (    file_identifier: amt$file_identifier;
     VAR status: ost$status);

{Design: The intent of this procedure is to rewind the current ANSI file to BOI.
{If the ANSI file begins on the current volume, this is just a matter of positioning
{after the most recent file header labels.  However, embedded tapemarks make the
{process of finding the most recent file header labels more difficult.  If the ANSI
{file began on a previous volume, we rewind the volume set and position forward by
{file sequence number until we find the original ANSI file.

    VAR
      attachment_options: ^array [1 .. 1] of fst$attachment_option,
      decrement_file_sequence: boolean,
      encountered_bov: boolean,
      error_action: bat$error_actions,
      label_group: fst$ansi_label_kinds,
      request_status: ost$status,
      returned_attributes: fst$tla_returned_attributes,
      skip_count: amt$skip_count,
      tape_failure_modes: amt$tape_failure_modes,
      target_file_sequence_no: 1 .. 9999;

    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering SL_REWIND_ANSI_FILE');
    rmp$log_debug_integer ('LABELED_TAPE_DEBUG: Value of LVP is: ',
          $INTEGER (tape_descriptor^.labeled_volume_position));

    status.normal := TRUE;
    decrement_file_sequence := FALSE;

    IF state_info^.put_op OR state_info^.eoi_labels_needed THEN
      rmp$log_debug_message ('Calling SL_PUT_END_OF_FILE_LABELS from SL_REWIND_ANSI_FILE');
      sl_put_end_of_file_labels (file_identifier, status);
      IF status.normal THEN
        sl_enable_read_after_write (file_identifier, status);
      IFEND;
      state_info^.put_op := FALSE;
    ELSE
      bap$tape_bm_align_position (file_identifier, tape_failure_modes, request_status);
      bai$process_request_status (file_identifier, amc$rewind_req, request_status, tape_failure_modes,
            error_action, status);
    IFEND;

    IF status.normal THEN
      PUSH attachment_options;
      attachment_options^ [1].selector := fsc$tape_attachment;
      attachment_options^ [1].tape_attachment.selector := fsc$tape_file_section_number;
      fsp$get_tape_label_attributes (file_instance^.local_file_name, fsc$tla_last_ansi_file_accessed,
            attachment_options^, returned_attributes, status);
      IF status.normal THEN
        rmp$log_debug_integer ('LABELED_TAPE_DEBUG: File Section Number is: ',
              attachment_options^ [1].tape_attachment.tape_file_section_number);
        IF (tape_descriptor^.initial_volume.header_labels = NIL) OR
              (tape_descriptor^.next_position.file_sequence_number = 1) OR
              ((tape_descriptor^.next_position.file_sequence_number = 2) AND
              bap$after_trailer_labels (tape_descriptor^.labeled_volume_position)) OR
              ((fsc$tape_file_section_number IN returned_attributes) AND
              (attachment_options^ [1].tape_attachment.tape_file_section_number <> 1)) THEN
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Rewinding volume set');
          IF bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
            target_file_sequence_no := tape_descriptor^.next_position.file_sequence_number - 1;
          ELSE
            target_file_sequence_no := tape_descriptor^.next_position.file_sequence_number;
          IFEND;
          rewind_tape (file_identifier, status);
          IF status.normal THEN
            file_instance^.previous_get_at_eoi := FALSE;
            sl_position_to_file_seq_number (file_identifier, target_file_sequence_no, status);
          IFEND;
        ELSE
          rmp$log_debug_message ('LABELED_TAPE_DEBUG: Current file on current volume');
          IF tape_descriptor^.volume_position <> amc$bov THEN
            IF bap$after_trailer_labels (tape_descriptor^.labeled_volume_position) THEN
              decrement_file_sequence := TRUE;
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: At END_OF_FILE_SET; Back 4 TMK');
              {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2* * *
              {                                             ^
              sl_advance_tapemark (file_identifier, amc$backward, 4, status);
            ELSE
              decrement_file_sequence := FALSE;
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: After header labels; Back 2 TMK');
              {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
              {                               ^
              sl_advance_tapemark (file_identifier, amc$backward, 2, status);
            IFEND;
            IF status.normal THEN
              file_instance^.previous_get_at_eoi := FALSE;
              {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
              {              ^
              sl_advance_tapemark (file_identifier, amc$forward, 1, status);
              {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
              {                ^
              bai$rewind_gfi;
            ELSEIF status.condition = ame$skip_encountered_bov THEN
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Encountered BOV');
              IF tape_descriptor^.volume_number = 1 THEN
                bai$init_boi_tape_position;
              ELSE
                bai$rewind_gfi;
              IFEND;
              status.normal := TRUE;
            ELSE
              rmp$log_debug_message ('LABELED_TAPE_DEBUG: Backward TMK skip failed');
              rmp$log_debug_status (status);
            IFEND;
          IFEND;
          IF status.normal THEN
            encountered_bov := FALSE;
            REPEAT
              sl_read_tape_labels (file_identifier, label_group, status);
              IF (status.normal AND fsp$file_header_labels (label_group)) THEN
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Setting LVP to after header labeels');
                IF decrement_file_sequence THEN
                  sl_decrement_file_sequence_no;
                IFEND;
                {   * EOF1  EOF2 * HDR1 HDR2* data * EOF1 EOF2*
                {                            ^
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_REWIND_ANSI_FILE - success');
                RETURN; {----->
              ELSEIF status.condition = ame$unexpected_tapemark THEN
                {   * EOF1 EOF2 * HDR1 HDR2 * * data * EOF1 EOF2*
                {                              ^
                sl_advance_tapemark (file_identifier, amc$backward, 3, status);
              ELSEIF status.condition = ame$invalid_tape_label THEN
                {   * EOF1 EOF2 * HDR1 HDR2* data * data * EOF1 EOF2*
                {                                  ^
                sl_advance_tapemark (file_identifier, amc$backward, 2, status);
              IFEND;
              IF status.normal THEN
                sl_advance_tapemark (file_identifier, amc$forward, 1, status);
                {   * EOF1 EOF2 * HDR1 HDR2* data * EOF1 EOF2*
                {                ^
              ELSEIF (status.condition = ame$skip_encountered_bov) AND (NOT encountered_bov) THEN
                rmp$log_debug_message ('LABELED_TAPE_DEBUG: Encountered BOV');
                encountered_bov := TRUE;
                status.normal := TRUE;
              ELSEIF encountered_bov THEN
                osp$set_status_condition (ame$label_sequence_error, status);
              IFEND;
            UNTIL (NOT status.normal);
            rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting SL_REWIND_ANSI_FILE -failure');
            rmp$log_debug_status (status);
          IFEND;
        IFEND;
      IFEND;
    IFEND;

  PROCEND sl_rewind_ansi_file;
?? OLDTITLE ??
?? NEWTITLE := '    sl_setup_volume_initialization', EJECT ??

  PROCEDURE sl_setup_volume_initialization
    (VAR status: ost$status);

    VAR
      logical_unit: iot$logical_unit;

    status.normal := TRUE;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Entering sl_setup_volume_initialization');
    IF tape_descriptor^.tape_attachment_information.tape_volume_initialization.element <> osc$null_name THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling cmp$get_logical_unit_number_r3');
      cmp$get_logical_unit_number_r3 (tape_descriptor^.tape_attachment_information.tape_volume_initialization.
            element, logical_unit, status);
      IF status.normal THEN
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling dmp$validate_tape_element');
        dmp$validate_tape_element (logical_unit, tape_descriptor^.requested_density, status);
      IFEND;
    ELSE
      logical_unit := 0;
    IFEND;
    IF status.normal THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Calling dmp$setup_tape_init_in_progress');
      dmp$setup_tape_init_in_progress ({in_progress} TRUE, tape_descriptor^.tape_attachment_information.
            tape_volume_initialization.element, logical_unit)
    IFEND;
    rmp$log_debug_message ('LABELED_TAPE_DEBUG: Exiting sl_setup_volume_initialization');

  PROCEND sl_setup_volume_initialization;
?? OLDTITLE ??
?? NEWTITLE := '    sl_store_authorized_access', EJECT ??

  PROCEDURE sl_store_authorized_access
    (    authorized_access: fst$file_access_options;
     VAR status: ost$status);

    VAR
      dynamic_label: ^bat$dynamic_label_attributes;

    status.normal := TRUE;

    dynamic_label := ^file_instance^.instance_attributes.dynamic_label;
    #UNCHECKED_CONVERSION (authorized_access, dynamic_label^.access_mode);

    IF dynamic_label^.open_position = amc$open_at_eoi THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing file access= BAC$APPEND($EOI)');
      state_info^.file_access := bac$append;
    ELSEIF pfc$shorten IN dynamic_label^.access_mode THEN
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing file access= BAC$WRITE');
      state_info^.file_access := bac$write;
    ELSEIF dynamic_label^.access_mode = $pft$usage_selections [pfc$append] THEN
      IF dynamic_label^.open_position = amc$open_at_boi THEN
        osp$set_status_condition (ame$improper_append_open, status);
        osp$append_status_file (osc$status_parameter_delimiter, file_instance^.local_file_name, status);
      ELSE
        rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing file access= BAC$APPEND');
        state_info^.file_access := bac$append;
      IFEND;
    ELSE
      rmp$log_debug_message ('LABELED_TAPE_DEBUG: Storing file access= BAC$READ');
      state_info^.file_access := bac$read;
    IFEND;

  PROCEND sl_store_authorized_access;
?? OLDTITLE ??
?? NEWTITLE := '    sl_tape_abnormal_termination', EJECT ??

  PROCEDURE sl_tape_abnormal_termination
    (    file_identifier: amt$file_identifier);

    VAR
      local_status: ost$status,
      tape_failure_modes: amt$tape_failure_modes;

    bap$tape_bm_close (file_identifier, tape_failure_modes, local_status);
    bai$init_boi_tape_position;
    state_info^.put_op := FALSE;
    state_info^.eoi_labels_needed := FALSE;
    tape_descriptor^.initial_volume.assigned := FALSE;
    tape_descriptor^.initial_volume.initial_read_labels_attempt := TRUE;
    IF NOT avp$removable_media_admin () THEN
      bap$free_tape_label_sequences ({free_initial_volume_sequence=} TRUE, tape_descriptor);
    IFEND;
    close_file_on_exit := TRUE;

  PROCEND sl_tape_abnormal_termination;
?? OLDTITLE ??
?? OLDTITLE ??

