]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/btape.c
Avoid segfault in dump_block() when the block_len is invalid
[bacula/bacula] / bacula / src / stored / btape.c
index 4082de27d903d37fdc68888bf74eaffb4b847d48..f4fa3aa6ef55f314f227f6b4b5449325cced041f 100644 (file)
@@ -1,17 +1,21 @@
 /*
-   Bacula® - The Network Backup Solution
+   Bacula(R) - The Network Backup Solution
 
+   Copyright (C) 2000-2015 Kern Sibbald
    Copyright (C) 2000-2014 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.
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
 
    You may use this file and others of this release according to the
    license defined in the LICENSE file, which includes the Affero General
    Public License, v3.0 ("AGPLv3") and some additional permissions and
    terms pursuant to its AGPLv3 Section 7.
 
-   Bacula® is a registered trademark of Kern Sibbald.
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
 /*
  *
@@ -34,8 +38,6 @@
 #include "vtape_dev.h"
 #endif
 
-/* Dummy functions */
-int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
 
 /* External subroutines */
@@ -138,7 +140,6 @@ static int vol_num = 0;
 
 static JCR *jcr = NULL;
 
-
 static void usage();
 static void terminate_btape(int sig);
 int get_cmd(const char *prompt);
@@ -464,7 +465,7 @@ static bool open_the_device()
    dev->rLock(false);
    Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
    if (!dev->open(dcr, OPEN_READ_WRITE)) {
-      Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
+      Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->print_errmsg());
       ok = false;
       goto bail_out;
    }
@@ -526,7 +527,7 @@ static void readlabelcmd()
       Pmsg1(0, _("I/O error on device: ERR=%s"), dev->bstrerror());
       break;
    case VOL_TYPE_ERROR:
-      Pmsg1(0, _("Volume type error: ERR=%s\n"), dev->errmsg);
+      Pmsg1(0, _("Volume type error: ERR=%s\n"), dev->print_errmsg());
       break;
    case VOL_NAME_ERROR:
       Pmsg0(0, _("Volume name error\n"));
@@ -855,8 +856,7 @@ static bool re_read_block_test()
    }
    Pmsg0(0, _("Backspace record OK.\n"));
    if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
-      berrno be;
-      Pmsg1(0, _("Read block failed! ERR=%s\n"), be.bstrerror(dev->dev_errno));
+      Pmsg1(0, _("Read block failed! ERR=%s\n"), dev->print_errmsg());
       goto bail_out;
    }
    memset(rec->data, 0, rec->data_len);
@@ -1117,8 +1117,9 @@ static bool write_two_files()
    /*
     * Set big max_file_size so that write_record_to_block
     * doesn't insert any additional EOF marks
+    * Do calculation in 64 bits to avoid overflow.
     */
-   dev->max_file_size = 2 * num_recs * dev->max_block_size;
+   dev->max_file_size = (uint64_t)2 * (uint64_t)num_recs * (uint64_t)dev->max_block_size;
    Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
       "I'm going to write %d records and an EOF\n"
       "then write %d records and an EOF, then rewind,\n"
@@ -1220,14 +1221,13 @@ static bool write_read_test()
    for (i=1; i<=2*num_recs; i++) {
 read_again:
       if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
-         berrno be;
          if (dev_state(dev, ST_EOF)) {
             Pmsg0(-1, _("Got EOF on tape.\n"));
             if (i == num_recs+1) {
                goto read_again;
             }
          }
-         Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, be.bstrerror(dev->dev_errno));
+         Pmsg2(0, _("Read block %d failed! ERR=%s\n"), i, dev->print_errmsg());
          goto bail_out;
       }
       memset(rec->data, 0, rec->data_len);
@@ -1339,7 +1339,6 @@ static bool position_test()
       }
 read_again:
       if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
-         berrno be;
          if (dev_state(dev, ST_EOF)) {
             Pmsg0(-1, _("Got EOF on tape.\n"));
             if (!got_eof) {
@@ -1348,7 +1347,7 @@ read_again:
             }
          }
          Pmsg4(0, _("Read block %d failed! file=%d blk=%d. ERR=%s\n\n"),
-            recno, file, blk, be.bstrerror(dev->dev_errno));
+            recno, file, blk, dev->print_errmsg());
          Pmsg0(0, _("This may be because the tape drive block size is not\n"
                     " set to variable blocking as normally used by Bacula.\n"
                     " Please see the Tape Testing chapter in the manual and \n"
@@ -2089,7 +2088,7 @@ static void scan_blocks()
             printf(_("Short block read.\n"));
             continue;
          }
-         printf(_("Error reading block. ERR=%s\n"), dev->bstrerror());
+         printf(_("Error reading block. ERR=%s\n"), dev->print_errmsg());
          goto bail_out;
       }
       if (block->block_len != block_size) {
@@ -2526,8 +2525,9 @@ static bool do_unfill()
 
    dev->close();
    dev->num_writers = 0;
+   dcr->clear_writing();
    if (!acquire_device_for_read(dcr)) {
-      Pmsg1(-1, "%s", dev->errmsg);
+      Pmsg1(-1, "%s", dev->print_errmsg());
       goto bail_out;
    }
    /*
@@ -2552,7 +2552,7 @@ static bool do_unfill()
    }
    Pmsg1(-1, _("Reading block %u.\n"), last_block_num);
    if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
-      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
+      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
       goto bail_out;
    }
    if (compare_blocks(last_block, block)) {
@@ -2589,8 +2589,9 @@ static bool do_unfill()
    }
 
    dev->clear_read();
+   dcr->clear_writing();
    if (!acquire_device_for_read(dcr)) {
-      Pmsg1(-1, "%s", dev->errmsg);
+      Pmsg1(-1, "%s", dev->print_errmsg());
       goto bail_out;
    }
 
@@ -2604,7 +2605,7 @@ static bool do_unfill()
    }
    Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
    if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
-      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
+      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
       goto bail_out;
    }
    if (compare_blocks(first_block, block)) {
@@ -2620,7 +2621,7 @@ static bool do_unfill()
    }
    Pmsg1(-1, _("Reading block %d.\n"), dev->block_num);
    if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
-      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->bstrerror());
+      Pmsg1(-1, _("Error reading block: ERR=%s\n"), dev->print_errmsg());
       goto bail_out;
    }
    if (compare_blocks(last_block, block)) {
@@ -2954,7 +2955,7 @@ static void usage()
 {
    fprintf(stderr, _(
 PROG_COPYRIGHT
-"\nVersion: %s (%s)\n\n"
+"\n%sVersion: %s (%s)\n\n"
 "Usage: btape <options> <device_name>\n"
 "       -b <file>   specify bootstrap file\n"
 "       -c <file>   set configuration file to file\n"
@@ -2964,7 +2965,7 @@ PROG_COPYRIGHT
 "       -s          turn off signals\n"
 "       -v          be verbose\n"
 "       -?          print this message.\n"
-"\n"), 2000, VERSION, BDATE);
+"\n"), 2000, "", VERSION, BDATE);
 
 }
 
@@ -3006,6 +3007,7 @@ get_cmd(const char *prompt)
 /* Dummies to replace askdir.c */
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
+bool    flush_jobmedia_queue(JCR *jcr) { return true; }
 
 bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
 {
@@ -3040,7 +3042,7 @@ bool dir_ask_sysop_to_mount_volume(DCR *dcr, bool /* writing */)
    if (dcr->VolumeName[0] == 0) {
       return dir_ask_sysop_to_create_appendable_volume(dcr);
    }
-   Pmsg1(-1, "%s", dev->errmsg);           /* print reason */
+   Pmsg1(-1, "%s", dev->print_errmsg());           /* print reason */
    if (dcr->VolumeName[0] == 0 || strcmp(dcr->VolumeName, "TestVolume2") == 0) {
       fprintf(stderr, _("Mount second Volume on device %s and press return when ready: "),
          dev->print_name());