]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/bls.c
Change copyright as per agreement with FSFE
[bacula/bacula] / bacula / src / stored / bls.c
index 771f8554841e60500030f995031f528a571fbfbc..ced369248a141696a8dc095e4827be3aaf02e7da 100644 (file)
@@ -1,34 +1,25 @@
 /*
-   Bacula® - The Network Backup Solution
-
-   Copyright (C) 2000-2012 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 three of the GNU Affero General Public
-   License as published by the Free Software Foundation and included
-   in the file LICENSE.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   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 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 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.
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2016 Kern Sibbald
+
+   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.
+
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
 /*
  *
  *  Dumb program to do an "ls" of a Bacula 1.0 mortal file.
- * 
+ *
  *  Kern Sibbald, MM
  *
  */
@@ -37,8 +28,6 @@
 #include "stored.h"
 #include "findlib/find.h"
 
-/* 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);
 
 static void do_blocks(char *infname);
@@ -60,13 +49,15 @@ static uint32_t num_files = 0;
 static ATTR *attr;
 static CONFIG *config;
 
+void *start_heap;
 #define CONFIG_FILE "bacula-sd.conf"
 char *configfile = NULL;
 STORES *me = NULL;                    /* our Global resource */
 bool forge_on = false;
 pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
-
+bool detect_errors = false;
+int  errors = 0;
 
 static FF_PKT *ff;
 
@@ -76,7 +67,7 @@ static void usage()
 {
    fprintf(stderr, _(
 PROG_COPYRIGHT
-"\nVersion: %s (%s)\n\n"
+"\n%sVersion: %s (%s)\n\n"
 "Usage: bls [options] <device-name>\n"
 "       -b <file>       specify a bootstrap file\n"
 "       -c <file>       specify a Storage configuration file\n"
@@ -91,7 +82,8 @@ PROG_COPYRIGHT
 "       -p              proceed inspite of errors\n"
 "       -v              be verbose\n"
 "       -V              specify Volume names (separated by |)\n"
-"       -?              print this message\n\n"), 2000, VERSION, BDATE);
+"       -E              Check records to detect errors\n"
+"       -?              print this message\n\n"), 2000, "", VERSION, BDATE);
    exit(1);
 }
 
@@ -119,12 +111,16 @@ int main (int argc, char *argv[])
 
    ff = init_find_files();
 
-   while ((ch = getopt(argc, argv, "b:c:d:e:i:jkLpvV:?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:c:d:e:i:jkLpvV:?E")) != -1) {
       switch (ch) {
       case 'b':
          bsrName = optarg;
          break;
 
+      case 'E':
+         detect_errors = true;
+         break;
+
       case 'c':                    /* specify config file */
          if (configfile != NULL) {
             free(configfile);
@@ -218,6 +214,8 @@ int main (int argc, char *argv[])
 
    config = new_config_parser();
    parse_sd_config(config, configfile, M_ERROR_TERM);
+   setup_me();
+   load_sd_plugins(me->plugin_directory);
 
    if (ff->included_files_list == NULL) {
       add_fname_to_include_list(ff, 0, "/");
@@ -227,7 +225,7 @@ int main (int argc, char *argv[])
       if (bsrName) {
          bsr = parse_bsr(NULL, bsrName);
       }
-      jcr = setup_jcr("bls", argv[i], bsr, VolumeName, 1); /* acquire for read */
+      jcr = setup_jcr("bls", argv[i], bsr, VolumeName, SD_READ);
       if (!jcr) {
          exit(1);
       }
@@ -263,6 +261,10 @@ int main (int argc, char *argv[])
    }
    term_include_exclude_files(ff);
    term_find_files(ff);
+
+   if (detect_errors) {
+      return (errors > 0)? 1 : 0;
+   }
    return 0;
 }
 
@@ -284,7 +286,7 @@ static void do_blocks(char *infname)
    char buf1[100], buf2[100];
    for ( ;; ) {
       if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
-         Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
+         Dmsg1(100, "!read_block(): ERR=%s\n", dev->print_errmsg());
          if (dev->at_eot()) {
             if (!mount_next_read_volume(dcr)) {
                Jmsg(jcr, M_INFO, 0, _("Got EOM at file %u on device %s, Volume \"%s\"\n"),
@@ -305,10 +307,11 @@ static void do_blocks(char *infname)
             Dmsg0(20, "read_record got eof. try again\n");
             continue;
          } else if (dev->is_short_block()) {
-            Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
+            Jmsg(jcr, M_INFO, 0, "%s", dev->print_errmsg());
             continue;
          } else {
             /* I/O error */
+            errors++;
             display_tape_error_status(jcr, dev);
             break;
          }
@@ -346,7 +349,7 @@ static void do_blocks(char *infname)
 static bool jobs_cb(DCR *dcr, DEV_RECORD *rec)
 {
    if (rec->FileIndex < 0) {
-      dump_label_record(dcr->dev, rec, verbose);
+      dump_label_record(dcr->dev, rec, verbose, detect_errors);
    }
    rec->remainder = 0;
    return true;
@@ -355,7 +358,9 @@ static bool jobs_cb(DCR *dcr, DEV_RECORD *rec)
 /* Do list job records */
 static void do_jobs(char *infname)
 {
-   read_records(dcr, jobs_cb, mount_next_read_volume);
+   if (!read_records(dcr, jobs_cb, mount_next_read_volume)) {
+      errors++;
+   }
 }
 
 /* Do an ls type listing of an archive */
@@ -365,7 +370,9 @@ static void do_ls(char *infname)
       dump_volume_label(dev);
       return;
    }
-   read_records(dcr, record_cb, mount_next_read_volume);
+   if (!read_records(dcr, record_cb, mount_next_read_volume)) {
+      errors++;
+   }
    printf("%u files found.\n", num_files);
 }
 
@@ -374,10 +381,18 @@ static void do_ls(char *infname)
  */
 static bool record_cb(DCR *dcr, DEV_RECORD *rec)
 {
-   if (rec->FileIndex < 0) {
-      get_session_record(dev, rec, &sessrec);
+   if (verbose && rec->FileIndex < 0) {
+      dump_label_record(dcr->dev, rec, verbose, false);
       return true;
    }
+   if (verbose) {
+      char buf1[100], buf2[100];
+      Pmsg6(000, "Record: FI=%s SessId=%d Strm=%s len=%u remlen=%d data_len=%d\n",
+         FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
+         stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_bytes, rec->remlen,
+         rec->data_len);
+   }
+
    /* File Attributes stream */
    if (rec->maskedStream == STREAM_UNIX_ATTRIBUTES ||
        rec->maskedStream == STREAM_UNIX_ATTRIBUTES_EX) {
@@ -396,7 +411,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
 
       if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) {
          if (verbose) {
-            Pmsg5(-1, _("FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n"),
+            Pmsg5(000, _("FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n"),
                   rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
          }
          print_ls_output(jcr, attr);
@@ -406,11 +421,11 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
       char data[100];
       int len = MIN(rec->data_len+1, sizeof(data));
       bstrncpy(data, rec->data, len);
-      Pmsg1(000, "Plugin data: %s\n", data);
+      Dmsg1(100, "Plugin data: %s\n", data);
    } else if (rec->Stream == STREAM_RESTORE_OBJECT) {
-      Pmsg0(000, "Restore Object record\n");
+      Dmsg0(100, "Restore Object record\n");
    }
-      
+
    return true;
 }
 
@@ -451,7 +466,7 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess
       break;
    default:
       rtype = _("Unknown");
-      Dmsg1(10, "FI rtype=%d unknown\n", rec->FileIndex);     
+      Dmsg1(10, "FI rtype=%d unknown\n", rec->FileIndex);
       break;
    }
    Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
@@ -467,13 +482,14 @@ static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sess
 bool    dir_find_next_appendable_volume(DCR *dcr) { return 1;}
 bool    dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten) { return 1; }
 bool    dir_create_jobmedia_record(DCR *dcr, bool zero) { return 1; }
+bool    flush_jobmedia_queue(JCR *jcr) { return true; }
 bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
 bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
 bool    dir_send_job_status(JCR *jcr) {return 1;}
 int     generate_job_event(JCR *jcr, const char *event) { return 1; }
-       
 
-bool dir_ask_sysop_to_mount_volume(DCR *dcr, int /*mode*/)
+
+bool dir_ask_sysop_to_mount_volume(DCR *dcr, bool /*writing*/)
 {
    DEVICE *dev = dcr->dev;
    fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
@@ -487,7 +503,6 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw  writing)
 {
    Dmsg0(100, "Fake dir_get_volume_info\n");
    dcr->setVolCatName(dcr->VolumeName);
-   dcr->VolCatInfo.VolCatParts = find_num_dvd_parts(dcr);
-   Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->getVolCatName(), dcr->VolCatInfo.VolCatParts);
+   Dmsg2(500, "Vol=%s VolType=%d\n", dcr->getVolCatName(), dcr->VolCatInfo.VolCatType);
    return 1;
 }