int position_blocks(int32_t count, uint8_t *sam_stat) { MHVTL_DBG(1, "position_blocks"); if (!tape_loaded(sam_stat)) return -1; if (MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; if (count < 0) { for (; count < 0; count++) { if (skip_to_prev_header(sam_stat)) return -1; if (raw_pos.hdr.blk_type == B_FILEMARK) { sam_no_sense(SD_FILEMARK, E_MARK, sam_stat); return -1; } } } else { for (; count > 0; count--) { if (skip_to_next_header(sam_stat)) return -1; if (raw_pos.hdr.blk_type == B_FILEMARK) { sam_no_sense(SD_FILEMARK, E_MARK, sam_stat); return -1; } } } return 0; }
int position_filemarks_back(uint32_t count, uint8_t *sam_stat) { uint32_t residual; int i; if (!tape_loaded(sam_stat)) return -1; if (mam.MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; /* Find the block number of the first filemark less than our current position. */ for (i = meta.filemark_count - 1; i >= 0; i--) if (filemarks[i] < raw_pos.hdr.blk_number) break; if (i + 1 >= count) return position_to_block(filemarks[i - count + 1], sam_stat); else { residual = count - i - 1; if (read_header(0, sam_stat)) return -1; sam_no_sense(SD_EOM, E_BOM, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } }
int position_blocks_forw(uint32_t count, uint8_t *sam_stat) { uint32_t residual; uint32_t blk_target; unsigned int i; if (!tape_loaded(sam_stat)) return -1; if (mam.MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; blk_target = raw_pos.hdr.blk_number + count; /* Find the first filemark forward from our current position, if any. */ for (i = 0; i < meta.filemark_count; i++) { MHVTL_DBG(3, "filemark at %ld", (unsigned long)filemarks[i]); if (filemarks[i] >= raw_pos.hdr.blk_number) break; } /* If there is one, see if it is between our current position and our desired destination. */ if (i < meta.filemark_count) { if (filemarks[i] >= blk_target) return position_to_block(blk_target, sam_stat); residual = blk_target - raw_pos.hdr.blk_number + 1; if (read_header(filemarks[i] + 1, sam_stat)) return -1; MHVTL_DBG(1, "Filemark encountered: block %d", filemarks[i]); sam_no_sense(SD_FILEMARK, E_MARK, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } if (blk_target > eod_blk_number) { residual = blk_target - eod_blk_number; if (read_header(eod_blk_number, sam_stat)) return -1; MHVTL_DBG(1, "EOD encountered"); sam_blank_check(E_END_OF_DATA, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } return position_to_block(blk_target, sam_stat); }
static int skip_prev_filemark(uint8_t *sam_stat) { MHVTL_DBG(1, "skip_prev_filemark"); if (raw_pos.hdr.blk_type == B_FILEMARK) raw_pos.hdr.blk_type = B_NOOP; while (raw_pos.hdr.blk_type != B_FILEMARK) { if (raw_pos.hdr.blk_type == B_BOT) { sam_no_sense(NO_SENSE, E_BOM, sam_stat); MHVTL_DBG(2, "Found Beginning of tape"); return -1; } if (skip_to_prev_header(sam_stat)) return -1; } return 0; }
int position_blocks_back(uint32_t count, uint8_t *sam_stat) { uint32_t residual; uint32_t blk_target; int i = -1; unsigned int num_filemarks = meta.filemark_count; if (!tape_loaded(sam_stat)) return -1; if (mam.MediumType == MEDIA_TYPE_WORM) OK_to_write = 0; MHVTL_DBG(2, "Position before movement: %d", raw_pos.hdr.blk_number); if (count < raw_pos.hdr.blk_number) blk_target = raw_pos.hdr.blk_number - count; else blk_target = 0; /* Find the first filemark prior to our current position, if any. */ if (num_filemarks > 0) { for (i = num_filemarks - 1; i >= 0; i--) { MHVTL_DBG(3, "filemark at %ld", (unsigned long)filemarks[i]); if (filemarks[i] < raw_pos.hdr.blk_number) break; } } /* If there is one, see if it is between our current position and our desired destination. */ if (i >= 0) { if (filemarks[i] < blk_target) return position_to_block(blk_target, sam_stat); residual = raw_pos.hdr.blk_number - blk_target; if (read_header(filemarks[i], sam_stat)) return -1; MHVTL_DBG(2, "Filemark encountered: block %d", filemarks[i]); sam_no_sense(SD_FILEMARK, E_MARK, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } if (count > raw_pos.hdr.blk_number) { residual = count - raw_pos.hdr.blk_number; if (read_header(0, sam_stat)) return -1; MHVTL_DBG(1, "BOM encountered"); sam_no_sense(SD_EOM, E_BOM, sam_stat); put_unaligned_be32(residual, &sense[3]); return -1; } return position_to_block(blk_target, sam_stat); }