+/*
+ Bacula® - The Network Backup Solution
+
+ Copyright (C) 2001-2007 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
+ 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 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.
+ The licensor of Bacula is the Free Software Foundation Europe
+ (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+ Switzerland, email:ftf@fsfeurope.org.
+*/
/*
*
* Program to scan a Bacula Volume and compare it with
*
* Version $Id$
*/
-/*
- 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
- version 2 as amended with additional clauses defined in the
- file LICENSE in the main source directory.
-
- 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
- the file LICENSE for additional details.
-
- */
#include "bacula.h"
#include "stored.h"
static int update_digest_record(B_DB *db, char *digest, DEV_RECORD *rec, int type);
-/* Global variables */
-#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
-int win32_client = 1;
-#else
-int win32_client = 0;
-#endif
-
-
/* Local variables */
static DEVICE *dev = NULL;
static B_DB *db;
static void usage()
{
fprintf(stderr, _(
-"Copyright (C) 2001-2005 Kern Sibbald.\n"
+PROG_COPYRIGHT
"\nVersion: %s (%s)\n\n"
"Usage: bscan [ options ] <bacula-archive>\n"
" -b bootstrap specify a bootstrap file\n"
" -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"), VERSION, BDATE);
+" -? print this message\n\n"), 2001, VERSION, BDATE);
exit(1);
}
setlocale(LC_ALL, "");
bindtextdomain("bacula", LOCALEDIR);
textdomain("bacula");
+ init_stack_dump();
my_name_is(argc, argv, "bscan");
init_msg(NULL, NULL);
+ OSDependentInit();
while ((ch = getopt(argc, argv, "b:c:d:h:mn:pP:rsSu:vV:w:?")) != -1) {
switch (ch) {
if (showProgress) {
char ed1[50];
struct stat sb;
- fstat(dev->fd, &sb);
+ fstat(dev->fd(), &sb);
currentVolumeSize = sb.st_size;
Pmsg1(000, _("First Volume Size = %sn"),
edit_uint64(currentVolumeSize, ed1));
Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
foreach_dlist(mdcr, dev->attached_dcrs) {
JCR *mjcr = mdcr->jcr;
+ Dmsg1(000, "========== JobId=%u ========\n", mjcr->JobId);
if (mjcr->JobId == 0) {
continue;
}
if (verbose) {
Pmsg1(000, _("Create JobMedia for Job %s\n"), mjcr->Job);
}
- if (dev->is_tape()) {
- mdcr->EndBlock = dcr->EndBlock;
- mdcr->EndFile = dcr->EndFile;
-// } else {
-// mdcr->EndBlock = (uint32_t)dcr->file_addr;
-// mdcr->EndFile = (uint32_t)(dcr->file_addr >> 32);
- }
+ mdcr->StartBlock = dcr->StartBlock;
+ mdcr->StartFile = dcr->StartFile;
+ mdcr->EndBlock = dcr->EndBlock;
+ mdcr->EndFile = dcr->EndFile;
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);
}
}
+
+ update_media_record(db, &mr);
+
/* 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.
if (showProgress) {
char ed1[50];
struct stat sb;
- fstat(dev->fd, &sb);
+ fstat(dev->fd(), &sb);
currentVolumeSize = sb.st_size;
Pmsg1(000, _("First Volume Size = %sn"),
edit_uint64(currentVolumeSize, ed1));
read_records(bjcr->read_dcr, record_cb, bscan_mount_next_read_volume);
+ if (update_db) {
+ db_write_batch_file_records(bjcr); /* used by bulk batch file insert */
+ }
free_attr(attr);
}
/* Create JobMedia record */
mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex;
create_jobmedia_record(db, mjcr);
- dev->attached_dcrs->remove(mjcr->read_dcr);
+ detach_dcr_from_dev(mjcr->read_dcr);
free_jcr(mjcr);
break;
case STREAM_WIN32_DATA:
case STREAM_FILE_DATA:
case STREAM_SPARSE_DATA:
+ case STREAM_ENCRYPTED_FILE_DATA:
+ case STREAM_ENCRYPTED_WIN32_DATA:
+ case STREAM_ENCRYPTED_MACOS_FORK_DATA:
+ /*
+ * For encrypted stream, this is an approximation.
+ * The data must be decrypted to know the correct length.
+ */
mjcr->JobBytes += rec->data_len;
if (rec->Stream == STREAM_SPARSE_DATA) {
mjcr->JobBytes -= sizeof(uint64_t);
break;
case STREAM_GZIP_DATA:
- mjcr->JobBytes += rec->data_len; /* No correct, we should expand it */
- free_jcr(mjcr); /* done using JCR */
+ case STREAM_ENCRYPTED_FILE_GZIP_DATA:
+ case STREAM_ENCRYPTED_WIN32_GZIP_DATA:
+ /* No correct, we should (decrypt and) expand it
+ done using JCR
+ */
+ mjcr->JobBytes += rec->data_len;
+ free_jcr(mjcr);
break;
case STREAM_SPARSE_GZIP_DATA:
break;
case STREAM_MD5_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_MD5_SIZE);
+ 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);
}
break;
case STREAM_SHA1_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_SHA1_SIZE);
+ 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);
}
break;
case STREAM_SHA256_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_SHA256_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA256_SIZE, true);
if (verbose > 1) {
Pmsg1(000, _("Got SHA256 record: %s\n"), digest);
}
break;
case STREAM_SHA512_DIGEST:
- bin_to_base64(digest, (char *)rec->data, CRYPTO_DIGEST_SHA512_SIZE);
+ bin_to_base64(digest, sizeof(digest), (char *)rec->data, CRYPTO_DIGEST_SHA512_SIZE, true);
if (verbose > 1) {
Pmsg1(000, _("Got SHA512 record: %s\n"), digest);
}
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);
+ Pmsg2(0, _("Unknown stream type!!! stream=%d len=%i\n"), rec->Stream, rec->data_len);
break;
}
return true;
/* 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);
mr->LabelDate = mktime(&tm);
}
lasttime = mr->LabelDate;
+ if (mr->VolJobs == 0) {
+ mr->VolJobs = 1;
+ }
+ if (mr->VolMounts == 0) {
+ mr->VolMounts = 1;
+ }
if (!update_db) {
return 1;
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;
JOBMEDIA_DBR jmr;
DCR *dcr = mjcr->read_dcr;
- if (dev->is_tape()) {
- dcr->EndBlock = dev->EndBlock;
- dcr->EndFile = dev->EndFile;
-#ifdef needed
- } else {
- dcr->EndBlock = (uint32_t)dev->file_addr;
- dcr->EndFile = (uint32_t)(dev->file_addr >> 32);
-#endif
- }
+ dcr->EndBlock = dev->EndBlock;
+ dcr->EndFile = dev->EndFile;
memset(&jmr, 0, sizeof(jmr));
jmr.JobId = mjcr->JobId;
jobjcr->VolSessionId = rec->VolSessionId;
jobjcr->VolSessionTime = rec->VolSessionTime;
jobjcr->ClientId = jr->ClientId;
- jobjcr->read_dcr = new_dcr(jobjcr, dev);
+ jobjcr->dcr = jobjcr->read_dcr = new_dcr(jobjcr, NULL, dev);
return jobjcr;
}
/* Dummies to replace askdir.c */
-bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing) { return 1;}
bool dir_find_next_appendable_volume(DCR *dcr) { return 1;}
bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; }
bool dir_create_jobmedia_record(DCR *dcr) { return 1; }
DEVICE *dev = dcr->dev;
Dmsg0(20, "Enter dir_ask_sysop_to_mount_volume\n");
/* Close device so user can use autochanger if desired */
- dev->close();
fprintf(stderr, _("Mount Volume \"%s\" on device %s and press return when ready: "),
dcr->VolumeName, dev->print_name());
+ dev->close();
getchar();
return true;
}
+
+bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
+{
+ Dmsg0(100, "Fake dir_get_volume_info\n");
+ bstrncpy(dcr->VolCatInfo.VolCatName, dcr->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
+ dcr->VolCatInfo.VolCatParts = find_num_dvd_parts(dcr);
+ Dmsg2(500, "Vol=%s num_parts=%d\n", dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.VolCatParts);
+ return 1;
+}