+
+ if (atEOD) {
+ errno = EIO;
+ return -1;
+ }
+
+ atBOT = atEOF = false;
+
+ /* check all block record */
+ for(i=0; (i < count) && !atEOF ; i++) {
+ nb = ::read(fd, &s, sizeof(uint32_t)); /* get size of next block */
+ if (nb == sizeof(uint32_t) && s) {
+ current_block++;
+ where = lseek(fd, s, SEEK_CUR); /* seek after this block */
+ } else {
+ Dmsg4(dbglevel, "read EOF %i:%i nb=%i s=%i\n",
+ current_file, current_block, nb,s);
+ errno = EIO;
+ ret = -1;
+ if (current_file < last_file) {
+ current_block = 0;
+ current_file++;
+ seek_file();
+ }
+ atEOF = true; /* stop the loop */
+ }
+ }
+
+ find_maxfile(); /* refresh stats */
+
+ if (where == file_size) {
+ atEOD = true;
+ }
+ return ret;
+}
+
+int faketape::bsr(int count)
+{
+ Dmsg2(dbglevel, "bsr current_block=%i count=%i\n",
+ current_block, count);
+
+ ASSERT(current_file >= 0);
+ ASSERT(count == 1);
+ ASSERT(fd >= 0);
+
+ check_eof();
+
+ if (!count) {
+ return 0;
+ }
+
+ int ret=0;
+ int last_f=0;
+ int last_b=0;
+
+ off_t last=-1, last2=-1;
+ off_t orig = lseek(fd, 0, SEEK_CUR);
+ int orig_f = current_file;
+ int orig_b = current_block;
+
+ current_block=0;
+ seek_file();
+
+ do {
+ if (!atEOF) {
+ last2 = last;
+ last = lseek(fd, 0, SEEK_CUR);
+ last_f = current_file;
+ last_b = current_block;
+ Dmsg5(dbglevel, "EOF=%i last=%lli orig=%lli %i:%i\n",
+ atEOF, last, orig, current_file, current_block);
+ }
+ ret = fsr(1);
+ } while ((lseek(fd, 0, SEEK_CUR) < orig) && (ret == 0));
+
+ if (last2 > 0 && atEOF) { /* we take the previous position */
+ lseek(fd, last2, SEEK_SET);
+ current_file = last_f;
+ current_block = last_b - 1;
+ Dmsg3(dbglevel, "set offset2=%lli %i:%i\n",
+ last, current_file, current_block);
+
+ } else if (last > 0) {
+ lseek(fd, last, SEEK_SET);
+ current_file = last_f;
+ current_block = last_b;
+ Dmsg3(dbglevel, "set offset=%lli %i:%i\n",
+ last, current_file, current_block);
+ } else {
+ lseek(fd, orig, SEEK_SET);
+ current_file = orig_f;
+ current_block = orig_b;
+ return -1;
+ }
+
+ Dmsg2(dbglevel, "bsr %i:%i\n", current_file, current_block);
+ atEOT = atEOF = atEOD = false;
+
+ return 0;