]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/vtape.c
Fix bat seg fault
[bacula/bacula] / bacula / src / stored / vtape.c
index e5c0b763f02e7f548dd3914ef970b9fe30fd0aa0..16d9019b860e16644c655badb3f8353627e965d9 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2008-2010 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation, which is 
    listed in the file LICENSE.
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    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.
@@ -62,110 +62,35 @@ Device {
 
 #include "vtape.h"
 
-static int dbglevel = 100;
-#define FILE_OFFSET 30
-vtape *ftape_list[FTAPE_MAX_DRIVE];
 
-static vtape *get_tape(int fd)
-{
-   ASSERT(fd >= 0);
+#ifdef USE_VTAPE
 
-   if (fd >= FTAPE_MAX_DRIVE) {
-      /* error */
-      return NULL;
-   }
-
-   return ftape_list[fd];
-}
-
-static bool put_tape(vtape *ftape)
-{
-   ASSERT(ftape != NULL);
-
-   int fd = ftape->get_fd();
-   if (fd >= FTAPE_MAX_DRIVE) {
-      /* error */
-      return false;
-   }
-   ftape_list[fd] = ftape;
-   return true;
-}
+static int dbglevel = 100;
+#define FILE_OFFSET 30
 
 void vtape_debug(int level)
 {
    dbglevel = level;
 }
 
-/****************************************************************/
-/* theses function will replace open/read/write/close/ioctl
- * in bacula core
- */
-int vtape_open(const char *pathname, int flags, ...)
-{
-   ASSERT(pathname != NULL);
-
-   int fd;
-   vtape *tape = new vtape();
-   fd = tape->open(pathname, flags);
-   if (fd > 0) {
-      put_tape(tape);
-   }
-   return fd;
-}
-
-ssize_t vtape_read(int fd, void *buffer, size_t count)
-{
-   vtape *tape = get_tape(fd);
-   ASSERT(tape != NULL);
-   return tape->read(buffer, count);
-}
-
-ssize_t vtape_write(int fd, const void *buffer, size_t count)
+int vtape::d_ioctl(int fd, ioctl_req_t request, char *op)
 {
-   vtape *tape = get_tape(fd);
-   ASSERT(tape != NULL);
-   return tape->write(buffer, count);
-}
-
-int vtape_close(int fd)
-{
-   vtape *tape = get_tape(fd);
-   ASSERT(tape != NULL);
-   tape->close();
-   delete tape;
-   return 0;
-}
-
-int vtape_ioctl(int fd, unsigned long int request, ...)
-{
-   va_list argp;
-   int result=0;
-
-   vtape *t = get_tape(fd);
-   if (!t) {
-      errno = EBADF;
-      return -1;
-   }
-
-   va_start(argp, request);
+   int result = 0;
 
    if (request == MTIOCTOP) {
-      result = t->tape_op(va_arg(argp, mtop *));
+      result = tape_op((mtop *)op);
    } else if (request == MTIOCGET) {
-      result = t->tape_get(va_arg(argp, mtget *));
+      result = tape_get((mtget *)op);
    } else if (request == MTIOCPOS) {
-      result = t->tape_pos(va_arg(argp, mtpos *));
+      result = tape_pos((mtpos *)op);
    } else {
       errno = ENOTTY;
       result = -1;
    }
-   va_end(argp);
 
    return result;
 }
 
-/****************************************************************/
-
 int vtape::tape_op(struct mtop *mt_com)
 {
    int result=0;
@@ -194,13 +119,13 @@ int vtape::tape_op(struct mtop *mt_com)
 
    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;
 
@@ -227,7 +152,7 @@ int vtape::tape_op(struct mtop *mt_com)
 
    case MTWEOF:                 /* Write mt_count filemarks. */
       do {
-        result = weof();
+         result = weof();
       } while (result == 0 && --count > 0);
       break;
 
@@ -262,19 +187,19 @@ int vtape::tape_op(struct mtop *mt_com)
 
    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;
@@ -416,6 +341,10 @@ int vtape::truncate_file()
    return 0;
 }
 
+vtape::~vtape()
+{
+}
+
 vtape::vtape()
 {
    fd = -1;
@@ -432,11 +361,8 @@ vtape::vtape()
    current_file = 0;
    current_block = -1;
 
-   max_block = 2*1024*2048;      /* 2GB */
-}
-
-vtape::~vtape()
-{
+   max_block = VTAPE_MAX_BLOCK;
+   Dmsg0(0, "I'm a vtape device\n");
 }
 
 int vtape::get_fd()
@@ -450,7 +376,7 @@ int vtape::get_fd()
  * vtape_header = sizeof(data)
  * if vtape_header == 0, this is a EOF
  */
-ssize_t vtape::write(const void *buffer, size_t count)
+ssize_t vtape::d_write(int, const void *buffer, size_t count)
 {
    ASSERT(online);
    ASSERT(current_file >= 0);
@@ -459,7 +385,7 @@ ssize_t vtape::write(const void *buffer, size_t count)
 
    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");
@@ -526,8 +452,8 @@ int vtape::weof()
    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;
@@ -575,20 +501,20 @@ int vtape::fsf()
    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");
@@ -610,12 +536,12 @@ int vtape::fsf()
 bool vtape::read_fm(VT_READ_FM_MODE read_all)
 {
    int ret;
-   uint32_t c;
+   uint32_t c = 0;
    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;
       }
    }
 
@@ -627,7 +553,7 @@ bool vtape::read_fm(VT_READ_FM_MODE read_all)
    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));
 }
@@ -642,10 +568,10 @@ int vtape::fsr(int count)
    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();
 
@@ -673,10 +599,10 @@ int vtape::fsr(int count)
                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 */
       }
    }
@@ -706,8 +632,8 @@ int vtape::bsr(int count)
    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;
 
@@ -725,7 +651,7 @@ int vtape::bsr(int count)
       lseek(fd, cur_FM, SEEK_SET);
       atEOF = false;
       if (current_file > 0) {
-        current_file--;
+         current_file--;
       }
       current_block=-1;
       errno = EIO;
@@ -735,7 +661,7 @@ int vtape::bsr(int count)
    /*
     * 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 {
@@ -746,7 +672,7 @@ int vtape::bsr(int count)
 
    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;
@@ -779,7 +705,7 @@ int vtape::bsr(int count)
    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;
@@ -788,6 +714,11 @@ int vtape::bsr(int count)
    return 0;
 }
 
+boffset_t vtape::lseek(int fd, off_t offset, int whence)
+{
+   return ::lseek(fd, offset, whence);
+}
+
 /* BSF => just before last EOF
  * EOF + BSF => just before EOF
  * file 0 + BSF => BOT + errno
@@ -843,7 +774,7 @@ int vtape::offline()
 /* A filemark is automatically written to tape if the last tape operation
  * before close was a write.
  */
-int vtape::close()
+int vtape::d_close(int)
 {
    check_eof();
    ::close(fd);
@@ -859,7 +790,7 @@ int vtape::close()
  * by returning zero bytes for two consecutive read calls.  The third read
  * returns an error.
  */
-ssize_t vtape::read(void *buffer, size_t count)
+ssize_t vtape::d_read(int, void *buffer, size_t count)
 {
    ASSERT(online);
    ASSERT(current_file >= 0);
@@ -890,7 +821,7 @@ ssize_t vtape::read(void *buffer, size_t count)
    /* 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;
    }
 
@@ -904,7 +835,7 @@ ssize_t vtape::read(void *buffer, size_t count)
    if (!s) {                    /* EOF */
       atEOF = true;
       if (read_fm(VT_SKIP_EOF)) {
-        current_file++;
+         current_file++;
       }
 
       return 0;
@@ -918,7 +849,7 @@ ssize_t vtape::read(void *buffer, size_t count)
       current_block = -1;
       Dmsg0(dbglevel, "EOT during reading\n");
       return -1;
-   }                   /* read ok */
+   }                    /* read ok */
 
    if (current_block >= 0) {
       current_block++;
@@ -927,14 +858,15 @@ ssize_t vtape::read(void *buffer, size_t count)
    return nb;
 }
 
-int vtape::open(const char *pathname, int uflags)
+int vtape::d_open(const char *pathname, int uflags)
 {
-   Dmsg2(dbglevel, "vtape::open(%s, %i)\n", pathname, uflags);
+   Dmsg2(dbglevel, "vtape::d_open(%s, %i)\n", pathname, uflags);
 
    online = true;               /* assume that drive contains a tape */
 
    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;
@@ -959,7 +891,9 @@ int vtape::open(const char *pathname, int uflags)
 
    /* 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;
    }
 
@@ -994,3 +928,4 @@ void vtape::dump()
          atEOF, atEOT, atEOD, atBOT);  
 }
 
+#endif  /* ! USE_VTAPE */