]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/bscan.c
Add V: to bextract and bscan
[bacula/bacula] / bacula / src / stored / bscan.c
index 9056f635f7419ee1f10730312dae77f507762469..4467a280fb5f1daccc95916ec30da9382d0ae561 100644 (file)
@@ -109,7 +109,7 @@ static void usage()
 "       -r                list records\n"
 "       -s                synchronize or store in database\n"
 "       -v                verbose\n"
-"       -V              specify Volume names (separated by |)\n"
+"       -V                specify Volume names (separated by |)\n"
 "       -w dir            specify working directory (default from conf file)\n"
 "       -?                print this message\n\n"));
    exit(1);
@@ -125,7 +125,7 @@ int main (int argc, char *argv[])
    init_msg(NULL, NULL);
 
 
-   while ((ch = getopt(argc, argv, "b:c:d:mn:p:rsu:vw:?")) != -1) {
+   while ((ch = getopt(argc, argv, "b:c:d:mn:p:rsu:vV:w:?")) != -1) {
       switch (ch) {
       case 'b':
         bsr = parse_bsr(NULL, optarg);
@@ -250,6 +250,39 @@ int main (int argc, char *argv[])
    return 0;
 }
   
+/*  
+ * We are at the end of reading a tape. Now, we simulate handling
+ *   the end of writing a tape by wiffling through the attached
+ *   jcrs creating jobmedia records.
+ */
+static int bscan_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
+{
+   Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
+   for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
+      if (verbose) {
+         Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job);
+      }
+      if (dev->state & ST_TAPE) {
+        mjcr->EndBlock = dev->EndBlock;
+        mjcr->EndFile = dev->EndFile;
+      } else {
+        mjcr->EndBlock = (uint32_t)dev->file_addr;
+        mjcr->StartBlock = (uint32_t)(dev->file_addr >> 32);
+      }
+      if (!create_jobmedia_record(db, mjcr)) {
+         Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
+           dev->VolCatInfo.VolCatName, mjcr->Job);
+      }
+   }  
+   /* Now let common read routine get up next tape. Note,
+    * we call mount_next... with bscan's jcr because that is where we
+    * have the Volume list, but we get attached.
+    */
+   int stat = mount_next_read_volume(jcr, dev, block);
+   /* we must once more detach ourselves (attached by mount_next ...) */
+   detach_jcr_from_device(dev, jcr); /* detach bscan jcr */
+   return stat;
+}
 
 static void do_scan()            
 {
@@ -262,9 +295,10 @@ static void do_scan()
    memset(&fsr, 0, sizeof(fsr));
    memset(&fr, 0, sizeof(fr));
 
+   /* Detach bscan's jcr as we are not a real Job on the tape */
    detach_jcr_from_device(dev, bjcr);
 
-   read_records(bjcr, dev, record_cb, mount_next_read_volume);
+   read_records(bjcr, dev, record_cb, bscan_mount_next_read_volume);
    release_device(bjcr, dev);
 
    free_attr(attr);
@@ -299,11 +333,12 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
          Pmsg0(000, _("Volume is prelabeled. This tape cannot be scanned.\n"));
         return;
         break;
+
       case VOL_LABEL:
         unser_volume_label(dev, rec);
         /* Check Pool info */
-        strcpy(pr.Name, dev->VolHdr.PoolName);
-        strcpy(pr.PoolType, dev->VolHdr.PoolType);
+        bstrncpy(pr.Name, dev->VolHdr.PoolName, sizeof(pr.Name));
+        bstrncpy(pr.PoolType, dev->VolHdr.PoolType, sizeof(pr.PoolType));
         if (db_get_pool_record(bjcr, db, &pr)) {
            if (verbose) {
                Pmsg1(000, _("Pool record for %s found in DB.\n"), pr.Name);
@@ -325,7 +360,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
         /* Check Media Info */
         memset(&mr, 0, sizeof(mr));
-        strcpy(mr.VolumeName, dev->VolHdr.VolName);
+        bstrncpy(mr.VolumeName, dev->VolHdr.VolName, sizeof(mr.VolumeName));
         mr.PoolId = pr.PoolId;
         if (db_get_media_record(bjcr, db, &mr)) {
            if (verbose) {
@@ -339,7 +374,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
                Pmsg1(000, _("VOL_LABEL: Media record not found for Volume: %s\n"),
                  mr.VolumeName);
            }
-           strcpy(mr.MediaType, dev->VolHdr.MediaType);
+           bstrncpy(mr.MediaType, dev->VolHdr.MediaType, sizeof(mr.MediaType));
            create_media_record(db, &mr, &dev->VolHdr);
         }
         if (strcmp(mr.MediaType, dev->VolHdr.MediaType) != 0) {
@@ -358,6 +393,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
 
          Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName);
         break;
+
       case SOS_LABEL:
         mr.VolJobs++;
         if (ignored_msgs > 0) {
@@ -430,6 +466,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
            return;
         }
         break;
+
       case EOS_LABEL:
         unser_session_label(&elabel, rec);
 
@@ -458,8 +495,10 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
         free_jcr(mjcr);
 
         break;
+
       case EOM_LABEL:
         break;
+
       case EOT_LABEL:             /* end of all tapes */
         /* 
          * Wiffle through all jobs still open and close
@@ -486,7 +525,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
         mr.VolBytes += mr.VolBlocks * WRITE_BLKHDR_LENGTH; /* approx. */
         mr.VolMounts++;
         update_media_record(db, &mr);
-         Pmsg3(0, _("End of Volume. VolFiles=%u VolBlocks=%u VolBytes=%s\n"), mr.VolFiles,
+         Pmsg3(0, _("End of all Volumes. VolFiles=%u VolBlocks=%u VolBytes=%s\n"), mr.VolFiles,
                    mr.VolBlocks, edit_uint64_with_commas(mr.VolBytes, ec1));
         break;
       default:
@@ -495,6 +534,19 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
       return;
    }
 
+   mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
+   if (!mjcr) {
+      if (mr.VolJobs > 0) {
+         Pmsg2(000, _("Could not find Job for SessId=%d SessTime=%d record.\n"),
+                     rec->VolSessionId, rec->VolSessionTime);
+      } else {
+        ignored_msgs++;
+      }
+      return;
+   }
+   if (mjcr->VolFirstIndex == 0) {
+      mjcr->VolFirstIndex = block->FirstIndex;
+   }
 
    /* File Attributes stream */
    switch (rec->Stream) {
@@ -511,20 +563,10 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
       }
        
       if (verbose > 1) {
-        uint32_t LinkFI;
-        decode_stat(attr->attr, &attr->statp, &LinkFI);
+        decode_stat(attr->attr, &attr->statp, &attr->LinkFI);
+        build_attr_output_fnames(bjcr, attr);
         print_ls_output(bjcr, attr);
       }
-      mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
-      if (!mjcr) {
-        if (mr.VolJobs > 0) {
-            Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"),
-                        rec->VolSessionId, rec->VolSessionTime);
-        } else {
-           ignored_msgs++;
-        }
-        return;
-      }
       fr.JobId = mjcr->JobId;
       fr.FileId = 0;
       if (db_get_file_attributes_record(bjcr, db, attr->fname, &fr)) {
@@ -542,16 +584,6 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
    case STREAM_WIN32_DATA:
    case STREAM_FILE_DATA:
    case STREAM_SPARSE_DATA:
-      mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
-      if (!mjcr) {
-        if (mr.VolJobs > 0) {
-            Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for File Data record.\n"),
-                        rec->VolSessionId, rec->VolSessionTime);
-        } else {
-           ignored_msgs++;
-        }
-        return;
-      }
       mjcr->JobBytes += rec->data_len;
       if (rec->Stream == STREAM_SPARSE_DATA) {
         mjcr->JobBytes -= sizeof(uint64_t);
@@ -561,47 +593,17 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
       break;
 
    case STREAM_GZIP_DATA:
-      mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
-      if (!mjcr) {
-        if (mr.VolJobs > 0) {
-            Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for GZIP Data record.\n"),
-                        rec->VolSessionId, rec->VolSessionTime);
-        } else {
-           ignored_msgs++;
-        }
-        return;
-      }
       mjcr->JobBytes += rec->data_len; /* No correct, we should expand it */
       free_jcr(mjcr);                /* done using JCR */
       break;
 
    case STREAM_SPARSE_GZIP_DATA:
-      mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
-      if (!mjcr) {
-        if (mr.VolJobs > 0) {
-            Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Sparse GZIP Data record.\n"),
-                        rec->VolSessionId, rec->VolSessionTime);
-        } else {
-           ignored_msgs++;
-        }
-        return;
-      }
       mjcr->JobBytes += rec->data_len - sizeof(uint64_t); /* No correct, we should expand it */
       free_jcr(mjcr);                /* done using JCR */
       break;
 
    /* Win32 GZIP stream */
    case STREAM_WIN32_GZIP_DATA:
-      mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
-      if (!mjcr) {
-        if (mr.VolJobs > 0) {
-            Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Win32 GZIP Data record.\n"),
-                        rec->VolSessionId, rec->VolSessionTime);
-        } else {
-           ignored_msgs++;
-        }
-        return;
-      }
       mjcr->JobBytes += rec->data_len;
       free_jcr(mjcr);                /* done using JCR */
       break;
@@ -1101,7 +1103,7 @@ static JCR *create_jcr(JOB_DBR *jr, DEV_RECORD *rec, uint32_t JobId)
 }
 
 /* Dummies to replace askdir.c */
-int    dir_get_volume_info(JCR *jcr, int writing) { return 1;}
+int    dir_get_volume_info(JCR *jcr, enum get_vol_info_rw  writing) { return 1;}
 int    dir_find_next_appendable_volume(JCR *jcr) { return 1;}
 int    dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
 int    dir_create_jobmedia_record(JCR *jcr) { return 1; }
@@ -1112,29 +1114,6 @@ int      dir_send_job_status(JCR *jcr) {return 1;}
 
 int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev)
 {
-   /*  
-    * We are at the end of reading a tape. Now, we simulate handling
-    *  the end of writing a tape by wiffling through the attached
-    *  jcrs creating jobmedia records.
-    */
-   Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
-   for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
-      if (verbose) {
-         Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job);
-      }
-      if (dev->state & ST_TAPE) {
-        mjcr->EndBlock = dev->EndBlock;
-        mjcr->EndFile = dev->EndFile;
-      } else {
-        mjcr->EndBlock = (uint32_t)dev->file_addr;
-        mjcr->StartBlock = (uint32_t)(dev->file_addr >> 32);
-      }
-      if (!create_jobmedia_record(db, mjcr)) {
-         Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
-           dev->VolCatInfo.VolCatName, mjcr->Job);
-      }
-   }
-
    fprintf(stderr, _("Mount Volume %s on device %s and press return when ready: "),
       jcr->VolumeName, dev_name(dev));
    getchar();