]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/bscan.c
Correct dvd code that breaks tape labeling
[bacula/bacula] / bacula / src / stored / bscan.c
index 17512b05d871b6fb3bee7a6da8aca898bd837aa8..48602c216e4679097e1ce002373d9d66de44403f 100644 (file)
@@ -10,7 +10,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2001-2005 Kern Sibbald
+   Copyright (C) 2001-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
@@ -48,15 +48,7 @@ static int  create_client_record(B_DB *db, CLIENT_DBR *cr);
 static int  create_fileset_record(B_DB *db, FILESET_DBR *fsr);
 static int  create_jobmedia_record(B_DB *db, JCR *jcr);
 static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId);
-static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type);
-
-
-/* Global variables */
-#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
-int win32_client = 1;
-#else
-int win32_client = 0;
-#endif
+static int update_digest_record(B_DB *db, char *digest, DEV_RECORD *rec, int type);
 
 
 /* Local variables */
@@ -106,8 +98,8 @@ pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
 static void usage()
 {
    fprintf(stderr, _(
-"Copyright (C) 2001-2005 Kern Sibbald.\n"
-"\nVersion: " VERSION " (" BDATE ")\n\n"
+"Copyright (C) 2001-%s Kern Sibbald.\n"
+"\nVersion: %s (%s)\n\n"
 "Usage: bscan [ options ] <bacula-archive>\n"
 "       -b bootstrap      specify a bootstrap file\n"
 "       -c <file>         specify configuration file\n"
@@ -124,7 +116,7 @@ static void usage()
 "       -v                verbose\n"
 "       -V <Volumes>      specify Volume names (separated by |)\n"
 "       -w <dir>          specify working directory (default from conf file)\n"
-"       -?                print this message\n\n"));
+"       -?                print this message\n\n"), BYEAR, VERSION, BDATE);
    exit(1);
 }
 
@@ -134,6 +126,10 @@ int main (int argc, char *argv[])
    struct stat stat_buf;
    char *VolumeName = NULL;
 
+   setlocale(LC_ALL, "");
+   bindtextdomain("bacula", LOCALEDIR);
+   textdomain("bacula");
+
    my_name_is(argc, argv, "bscan");
    init_msg(NULL, NULL);
 
@@ -255,7 +251,7 @@ int main (int argc, char *argv[])
    if (!bjcr) {
       exit(1);
    }
-   dev = bjcr->dcr->dev;
+   dev = bjcr->read_dcr->dev;
    if (showProgress) {
       char ed1[50];
       struct stat sb;
@@ -278,12 +274,17 @@ int main (int argc, char *argv[])
    }
 
    do_scan();
-   printf("Records %sadded or updated in the catalog:\n%7d Media\n%7d Pool\n%7d Job\n%7d File\n",
-      update_db?"":"would have been ",
-      num_media, num_pools, num_jobs, num_files);
+   if (update_db) {
+      printf("Records added or updated in the catalog:\n%7d Media\n%7d Pool\n%7d Job\n%7d File\n",
+         num_media, num_pools, num_jobs, num_files);
+   }
+   else {
+      printf("Records would have been added or updated in the catalog:\n%7d Media\n%7d Pool\n%7d Job\n%7d File\n",
+         num_media, num_pools, num_jobs, num_files);
+   }
 
    free_jcr(bjcr);
-   term_dev(dev);
+   dev->term();
    return 0;
 }
 
@@ -312,6 +313,7 @@ static bool bscan_mount_next_read_volume(DCR *dcr)
 //       mdcr->EndBlock = (uint32_t)dcr->file_addr;
 //       mdcr->EndFile = (uint32_t)(dcr->file_addr >> 32);
       }
+      mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex;
       if (!create_jobmedia_record(db, mjcr)) {
          Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
             dev->VolCatInfo.VolCatName, mjcr->Job);
@@ -347,7 +349,7 @@ static void do_scan()
 
    /* Detach bscan's jcr as we are not a real Job on the tape */
 
-   read_records(bjcr->dcr, record_cb, bscan_mount_next_read_volume);
+   read_records(bjcr->read_dcr, record_cb, bscan_mount_next_read_volume);
 
    free_attr(attr);
 }
@@ -363,13 +365,14 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
    DEVICE *dev = dcr->dev;
    JCR *bjcr = dcr->jcr;
    DEV_BLOCK *block = dcr->block;
+   char digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)];
 
    if (rec->data_len > 0) {
       mr.VolBytes += rec->data_len + WRITE_RECHDR_LENGTH; /* Accumulate Volume bytes */
-      if (showProgress) {
+      if (showProgress && currentVolumeSize > 0) {
          int pct = (mr.VolBytes * 100) / currentVolumeSize;
          if (pct != last_pct) {
-            fprintf(stdout, "done: %d%%\n", pct);
+            fprintf(stdout, _("done: %d%%\n"), pct);
             fflush(stdout);
             last_pct = pct;
          }
@@ -490,10 +493,11 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
 
          /* process label, if Job record exists don't update db */
          mjcr = create_job_record(db, &jr, &label, rec);
-         dcr = mjcr->dcr;
+         dcr = mjcr->read_dcr;
          update_db = save_update_db;
 
          jr.PoolId = pr.PoolId;
+#ifdef xxx
          /* Set start positions into JCR */
          if (dev->is_tape()) {
             /*
@@ -506,6 +510,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
             dcr->StartBlock = (uint32_t)dev->file_addr;
             dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
          }
+#endif
          mjcr->start_time = jr.StartTime;
          mjcr->JobLevel = jr.JobLevel;
 
@@ -559,8 +564,9 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
          mjcr->JobStatus = JS_Terminated;
 
          /* Create JobMedia record */
+         mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex;
          create_jobmedia_record(db, mjcr);
-         dev->attached_dcrs->remove(mjcr->dcr);
+         dev->attached_dcrs->remove(mjcr->read_dcr);
          free_jcr(mjcr);
 
          break;
@@ -592,7 +598,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
                if (!db_update_job_end_record(bjcr, db, &jr)) {
                   Pmsg1(0, _("Could not update job record. ERR=%s\n"), db_strerror(db));
                }
-               mjcr->dcr = NULL;
+               mjcr->read_dcr = NULL;
                free_jcr(mjcr);
             }
          }
@@ -620,7 +626,7 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
       }
       return true;
    }
-   dcr = mjcr->dcr;
+   dcr = mjcr->read_dcr;
    if (dcr->VolFirstIndex == 0) {
       dcr->VolFirstIndex = block->FirstIndex;
    }
@@ -688,24 +694,51 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
       free_jcr(mjcr);                 /* done using JCR */
       break;
 
-   case STREAM_MD5_SIGNATURE:
-      char MD5buf[50];
-      bin_to_base64(MD5buf, (char *)rec->data, 16); /* encode 16 bytes */
+   case STREAM_MD5_DIGEST:
+      bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_MD5_SIZE, true);
+      if (verbose > 1) {
+         Pmsg1(000, _("Got MD5 record: %s\n"), digest);
+      }
+      update_digest_record(db, digest, rec, CRYPTO_DIGEST_MD5);
+      break;
+
+   case STREAM_SHA1_DIGEST:
+      bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA1_SIZE, true);
+      if (verbose > 1) {
+         Pmsg1(000, _("Got SHA1 record: %s\n"), digest);
+      }
+      update_digest_record(db, digest, rec, CRYPTO_DIGEST_SHA1);
+      break;
+
+   case STREAM_SHA256_DIGEST:
+      bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA256_SIZE, true);
       if (verbose > 1) {
-         Pmsg1(000, _("Got MD5 record: %s\n"), MD5buf);
+         Pmsg1(000, _("Got SHA256 record: %s\n"), digest);
       }
-      update_SIG_record(db, MD5buf, rec, MD5_SIG);
+      update_digest_record(db, digest, rec, CRYPTO_DIGEST_SHA256);
       break;
 
-   case STREAM_SHA1_SIGNATURE:
-      char SIGbuf[50];
-      bin_to_base64(SIGbuf, (char *)rec->data, 20); /* encode 20 bytes */
+   case STREAM_SHA512_DIGEST:
+      bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA512_SIZE, true);
       if (verbose > 1) {
-         Pmsg1(000, _("Got SHA1 record: %s\n"), SIGbuf);
+         Pmsg1(000, _("Got SHA512 record: %s\n"), digest);
       }
-      update_SIG_record(db, SIGbuf, rec, SHA1_SIG);
+      update_digest_record(db, digest, rec, CRYPTO_DIGEST_SHA512);
       break;
 
+   case STREAM_ENCRYPTED_SESSION_DATA:
+      // TODO landonf: Investigate crypto support in bscan
+      if (verbose > 1) {
+         Pmsg0(000, _("Got signed digest record\n"));
+      }
+      break;
+
+   case STREAM_SIGNED_DIGEST:
+      // TODO landonf: Investigate crypto support in bscan
+      if (verbose > 1) {
+         Pmsg0(000, _("Got signed digest record\n"));
+      }
+      break;
 
    case STREAM_PROGRAM_NAMES:
       if (verbose) {
@@ -718,6 +751,12 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
          Pmsg0(000, _("Got Prog Data Stream record.\n"));
       }
       break;
+
+   case STREAM_UNIX_ATTRIBUTES_ACCESS_ACL:   /* Standard ACL attributes on UNIX */
+   case STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL:  /* Default ACL attributes on UNIX */
+      /* Ignore Unix attributes */
+      break;
+
    default:
       Pmsg2(0, _("Unknown stream type!!! stream=%d data=%s\n"), rec->Stream, rec->data);
       break;
@@ -749,6 +788,10 @@ static void bscan_free_jcr(JCR *jcr)
       free_dcr(jcr->dcr);
       jcr->dcr = NULL;
    }
+   if (jcr->read_dcr) {
+      free_dcr(jcr->read_dcr);
+      jcr->read_dcr = NULL;
+   }
    Dmsg0(200, "End bscan free_jcr\n");
 }
 
@@ -760,7 +803,7 @@ static int create_file_attributes_record(B_DB *db, JCR *mjcr,
                                char *fname, char *lname, int type,
                                char *ap, DEV_RECORD *rec)
 {
-   DCR *dcr = mjcr->dcr;
+   DCR *dcr = mjcr->read_dcr;
    ar.fname = fname;
    ar.link = lname;
    ar.ClientId = mjcr->ClientId;
@@ -801,6 +844,7 @@ static int create_media_record(B_DB *db, MEDIA_DBR *mr, VOLUME_LABEL *vl)
    /* We mark Vols as Archive to keep them from being re-written */
    bstrncpy(mr->VolStatus, "Archive", sizeof(mr->VolStatus));
    mr->VolRetention = 365 * 3600 * 24; /* 1 year */
+   mr->Enabled = 1;
    if (vl->VerNum >= 11) {
       mr->FirstWritten = btime_to_utime(vl->write_btime);
       mr->LabelDate    = btime_to_utime(vl->label_btime);
@@ -1029,8 +1073,8 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel,
       return 0;
    }
    if (verbose) {
-      Pmsg2(000, _("Updated Job termination record for JobId=%u TermStat=%c\n"), jr->JobId,
-         jr->JobStatus);
+      Pmsg3(000, _("Updated Job termination record for JobId=%u Level=%s TermStat=%c\n"), 
+         jr->JobId, job_level_to_str(mjcr->JobLevel), jr->JobStatus);
    }
    if (verbose > 1) {
       const char *term_msg;
@@ -1092,7 +1136,7 @@ static int update_job_record(B_DB *db, JOB_DBR *jr, SESSION_LABEL *elabel,
 static int create_jobmedia_record(B_DB *db, JCR *mjcr)
 {
    JOBMEDIA_DBR jmr;
-   DCR *dcr = mjcr->dcr;
+   DCR *dcr = mjcr->read_dcr;
 
    if (dev->is_tape()) {
       dcr->EndBlock = dev->EndBlock;
@@ -1108,7 +1152,7 @@ static int create_jobmedia_record(B_DB *db, JCR *mjcr)
    jmr.JobId = mjcr->JobId;
    jmr.MediaId = mr.MediaId;
    jmr.FirstIndex = dcr->VolFirstIndex;
-   jmr.LastIndex = dcr->FileIndex;
+   jmr.LastIndex = dcr->VolLastIndex;
    jmr.StartFile = dcr->StartFile;
    jmr.EndFile = dcr->EndFile;
    jmr.StartBlock = dcr->StartBlock;
@@ -1133,7 +1177,7 @@ static int create_jobmedia_record(B_DB *db, JCR *mjcr)
 /*
  * Simulate the database call that updates the MD5/SHA1 record
  */
-static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type)
+static int update_digest_record(B_DB *db, char *digest, DEV_RECORD *rec, int type)
 {
    JCR *mjcr;
 
@@ -1153,7 +1197,7 @@ static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type)
       return 1;
    }
 
-   if (!db_add_SIG_to_file_record(bjcr, db, mjcr->FileId, SIGbuf, type)) {
+   if (!db_add_digest_to_file_record(bjcr, db, mjcr->FileId, digest, type)) {
       Pmsg1(0, _("Could not add MD5/SHA1 to File record. ERR=%s\n"), db_strerror(db));
       free_jcr(mjcr);
       return 0;
@@ -1187,7 +1231,8 @@ static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId)
    jobjcr->VolSessionId = rec->VolSessionId;
    jobjcr->VolSessionTime = rec->VolSessionTime;
    jobjcr->ClientId = jr->ClientId;
-   new_dcr(jobjcr, dev);
+   jobjcr->read_dcr = new_dcr(jobjcr, dev);
+
    return jobjcr;
 }
 
@@ -1200,20 +1245,14 @@ 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; }
-VOLRES *new_volume(DCR *dcr, const char *VolumeName) { return NULL; }
-bool    free_volume(DEVICE *dev) { return true; }
-void    free_unused_volume(DCR *dcr) { }
 
 bool dir_ask_sysop_to_mount_volume(DCR *dcr)
 {
    DEVICE *dev = dcr->dev;
    Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
    /* Close device so user can use autochanger if desired */
-   if (dev_cap(dev, CAP_OFFLINEUNMOUNT)) {
-      offline_dev(dev);
-   }
-   force_close_device(dev);
-   fprintf(stderr, "Mount Volume \"%s\" on device %s and press return when ready: ",
+   dev->close();
+   fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
          dcr->VolumeName, dev->print_name());
    getchar();
    return true;