Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Bacula® is a registered trademark of John Walker.
+ Bacula® is a registered trademark of Kern Sibbald.
The licensor of Bacula is the Free Software Foundation Europe
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
#include "vtape.h"
+
+#ifdef USE_VTAPE
+
static int dbglevel = 100;
#define FILE_OFFSET 30
vtape *ftape_list[FTAPE_MAX_DRIVE];
return fd;
}
-int vtape_read(int fd, void *buffer, unsigned int count)
+ssize_t vtape_read(int fd, void *buffer, size_t count)
{
vtape *tape = get_tape(fd);
ASSERT(tape != NULL);
return tape->read(buffer, count);
}
-int vtape_write(int fd, const void *buffer, unsigned int count)
+ssize_t vtape_write(int fd, const void *buffer, size_t count)
{
vtape *tape = get_tape(fd);
ASSERT(tape != NULL);
return 0;
}
-int vtape_ioctl(int fd, unsigned long int request, ...)
+int vtape_ioctl(int fd, ioctl_req_t request, ...)
{
va_list argp;
- int result=0;
+ int result = 0;
vtape *t = get_tape(fd);
if (!t) {
return result;
}
-/****************************************************************/
-
int vtape::tape_op(struct mtop *mt_com)
{
int result=0;
case MTFSF: /* Forward space over mt_count filemarks. */
do {
- result = fsf();
+ result = fsf();
} while (--count > 0 && result == 0);
break;
case MTBSF: /* Backward space over mt_count filemarks. */
do {
- result = bsf();
+ result = bsf();
} while (--count > 0 && result == 0);
break;
case MTWEOF: /* Write mt_count filemarks. */
do {
- result = weof();
+ result = weof();
} while (result == 0 && --count > 0);
break;
case MTEOM:/* Go to the end of the recorded media (for appending files). */
while (next_FM) {
- lseek(fd, next_FM, SEEK_SET);
- if (read_fm(VT_READ_EOF)) {
- current_file++;
- }
+ lseek(fd, next_FM, SEEK_SET);
+ if (read_fm(VT_READ_EOF)) {
+ current_file++;
+ }
}
- off_t l;
+ boffset_t l;
while (::read(fd, &l, sizeof(l)) > 0) {
- if (l) {
- lseek(fd, l, SEEK_CUR);
- } else {
- ASSERT(0);
- }
- Dmsg0(dbglevel, "skip 1 block\n");
+ if (l) {
+ lseek(fd, l, SEEK_CUR);
+ } else {
+ ASSERT(0);
+ }
+ Dmsg0(dbglevel, "skip 1 block\n");
}
current_block = -1;
atEOF = false;
current_file = 0;
current_block = -1;
- max_block = 2*1024*2048; /* 2GB */
+ max_block = VTAPE_MAX_BLOCK;
}
vtape::~vtape()
}
/*
- * TODO: check if after a write op, and other tape op put a EOF
+ * Write a variable block of count size.
+ * block = vtape_header + data
+ * vtape_header = sizeof(data)
+ * if vtape_header == 0, this is a EOF
*/
-int vtape::write(const void *buffer, unsigned int count)
+ssize_t vtape::write(const void *buffer, size_t count)
{
ASSERT(online);
ASSERT(current_file >= 0);
ASSERT(count > 0);
ASSERT(buffer);
- unsigned int nb;
+ ssize_t nb;
Dmsg3(dbglevel*2, "write len=%i %i:%i\n",
- count, current_file,current_block);
+ count, current_file,current_block);
if (atEOT) {
Dmsg0(dbglevel, "write nothing, EOT !\n");
::write(fd, &size, sizeof(uint32_t));
nb = ::write(fd, buffer, count);
- if (nb != count) {
+ if (nb != (ssize_t)count) {
atEOT = true;
Dmsg2(dbglevel,
"Not enough space writing only %i of %i requested\n",
cur_FM = lseek(fd, 0, SEEK_CUR); // current position
/* update previous next_FM */
- lseek(fd, last_FM + sizeof(uint32_t)+sizeof(off_t), SEEK_SET);
- ::write(fd, &cur_FM, sizeof(off_t));
+ lseek(fd, last_FM + sizeof(uint32_t)+sizeof(boffset_t), SEEK_SET);
+ ::write(fd, &cur_FM, sizeof(boffset_t));
lseek(fd, cur_FM, SEEK_SET);
next_FM = 0;
atBOT = false;
Dmsg2(dbglevel+1, "fsf %i <= %i\n", current_file, last_file);
- if (next_FM > cur_FM) { /* not the last file */
+ if (next_FM > cur_FM) { /* not the last file */
lseek(fd, next_FM, SEEK_SET);
read_fm(VT_READ_EOF);
current_file++;
atEOF = true;
ret = 0;
- } else if (atEOF) { /* last file mark */
+ } else if (atEOF) { /* last file mark */
current_block=-1;
errno = EIO;
atEOF = false;
atEOD = true;
- } else { /* last file, but no at the end */
+ } else { /* last file, but no at the end */
fsr(100000);
Dmsg0(dbglevel, "Try to FSF after EOT\n");
if (read_all == VT_READ_EOF) {
::read(fd, &c, sizeof(c));
if (c != 0) {
- lseek(fd, cur_FM, SEEK_SET);
- return false;
+ lseek(fd, cur_FM, SEEK_SET);
+ return false;
}
}
current_block=0;
Dmsg3(dbglevel, "Read FM cur=%lli last=%lli next=%lli\n",
- cur_FM, last_FM, next_FM);
+ cur_FM, last_FM, next_FM);
return (ret == sizeof(next_FM));
}
ASSERT(fd >= 0);
int i,nb, ret=0;
- off_t where=0;
+ boffset_t where=0;
uint32_t s;
Dmsg4(dbglevel, "fsr %i:%i EOF=%i c=%i\n",
- current_file,current_block,atEOF,count);
+ current_file,current_block,atEOF,count);
check_eof();
current_file, current_block, nb,s);
errno = EIO;
ret = -1;
- if (next_FM) {
+ if (next_FM) {
current_file++;
- read_fm(VT_SKIP_EOF);
- }
+ read_fm(VT_SKIP_EOF);
+ }
atEOF = true; /* stop the loop */
}
}
int last_f=0;
int last_b=0;
- off_t last=-1, last2=-1;
- off_t orig = lseek(fd, 0, SEEK_CUR);
+ boffset_t last=-1, last2=-1;
+ boffset_t orig = lseek(fd, 0, SEEK_CUR);
int orig_f = current_file;
int orig_b = current_block;
lseek(fd, cur_FM, SEEK_SET);
atEOF = false;
if (current_file > 0) {
- current_file--;
+ current_file--;
}
current_block=-1;
errno = EIO;
/*
* First, go to cur/last_FM and read all blocks to find the good one
*/
- if (cur_FM == orig) { /* already just before EOF */
+ if (cur_FM == orig) { /* already just before EOF */
lseek(fd, last_FM, SEEK_SET);
} else {
do {
if (!atEOF) {
- last2 = last; /* keep track of the 2 last blocs position */
+ last2 = last; /* keep track of the 2 last blocs position */
last = lseek(fd, 0, SEEK_CUR);
last_f = current_file;
last_b = current_block;
Dmsg2(dbglevel, "bsr %i:%i\n", current_file, current_block);
errno=0;
atEOT = atEOF = atEOD = false;
- atBOT = (lseek(fd, 0, SEEK_CUR) - (sizeof(uint32_t)+2*sizeof(off_t))) == 0;
+ atBOT = (lseek(fd, 0, SEEK_CUR) - (sizeof(uint32_t)+2*sizeof(boffset_t))) == 0;
if (orig_b == -1) {
current_block = orig_b;
* When a filemark is encountered while reading, the following happens. If
* there are data remaining in the buffer when the filemark is found, the
* buffered data is returned. The next read returns zero bytes. The following
- * read returns data from the next file. The end of recorded data is sig‐
- * naled by returning zero bytes for two consecutive read calls. The third
- * read returns an error.
+ * read returns data from the next file. The end of recorded data is signaled
+ * by returning zero bytes for two consecutive read calls. The third read
+ * returns an error.
*/
-int vtape::read(void *buffer, unsigned int count)
+ssize_t vtape::read(void *buffer, size_t count)
{
ASSERT(online);
ASSERT(current_file >= 0);
- unsigned int nb;
+ ssize_t nb;
uint32_t s;
Dmsg2(dbglevel*2, "read %i:%i\n", current_file, current_block);
/* reading size of data */
nb = ::read(fd, &s, sizeof(uint32_t));
if (nb <= 0) {
- atEOF = true; /* TODO: check this */
+ atEOF = true; /* TODO: check this */
return 0;
}
if (!s) { /* EOF */
atEOF = true;
if (read_fm(VT_SKIP_EOF)) {
- current_file++;
+ current_file++;
}
return 0;
/* reading data itself */
nb = ::read(fd, buffer, s);
- if (s != nb) { /* read error */
+ if (nb != (ssize_t)s) { /* read error */
errno=EIO;
atEOT=true;
current_block = -1;
Dmsg0(dbglevel, "EOT during reading\n");
return -1;
- } /* read ok */
+ } /* read ok */
if (current_block >= 0) {
current_block++;
struct stat statp;
if (stat(pathname, &statp) != 0) {
+ fd = -1;
Dmsg1(dbglevel, "Can't stat on %s\n", pathname);
if (uflags & O_NONBLOCK) {
online = false;
/* If the vtape is empty, start by writing a EOF */
if (online && !read_fm(VT_READ_EOF)) {
- weof();
+ lseek(fd, 0, SEEK_SET); /* rewind */
+ cur_FM = next_FM = last_FM = 0; /* reset */
+ weof(); /* write the first EOF */
last_file = current_file=0;
}
file_block = statp.st_blocks;
}
- Dmsg1(dbglevel+1, "update_pos=%i\n", file_block);
+ Dmsg1(dbglevel*2, "update_pos=%i\n", file_block);
if (file_block > max_block) {
atEOT = true;
atEOF, atEOT, atEOD, atBOT);
}
+#else /* USE_VTAPE */
+
+int vtape_ioctl(int fd, ioctl_req_t request, ...)
+{
+ return -1;
+}
+
+int vtape_open(const char *pathname, int flags, ...)
+{
+ return -1;
+}
+
+int vtape_close(int fd)
+{
+ return -1;
+}
+
+void vtape_debug(int level)
+{
+}
+
+ssize_t vtape_read(int fd, void *buffer, size_t count)
+{
+ return -1;
+}
+
+ssize_t vtape_write(int fd, const void *buffer, size_t count)
+{
+ return -1;
+}
+
+#endif /* ! USE_VTAPE */