*
* Dumb program to extract files from a Bacula backup.
*
- * Kern E. Sibbald, 2000
+ * Kern E. Sibbald, MM
*
* Version $Id$
*
#endif
static void do_extract(char *fname);
-static bool record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
+static bool record_cb(DCR *dcr, DEV_RECORD *rec);
static DEVICE *dev = NULL;
static DCR *dcr;
static void usage()
{
fprintf(stderr,
+"Copyright (C) 2000-2004 Kern Sibbald and John Walker.\n"
"\nVersion: " VERSION " (" BDATE ")\n\n"
"Usage: bextract <options> <bacula-archive-device-name> <directory-to-store-files>\n"
" -b <file> specify a bootstrap file\n"
" -e <file> exclude list\n"
" -i <file> include list\n"
" -p proceed inspite of I/O errors\n"
+" -v verbose\n"
" -V <volumes> specify Volume names (separated by |)\n"
" -? print this message\n\n");
exit(1);
init_include_exclude_files(ff);
binit(&bfd);
- while ((ch = getopt(argc, argv, "b:c:d:e:i:pV:?")) != -1) {
+ while ((ch = getopt(argc, argv, "b:c:d:e:i:pvV:?")) != -1) {
switch (ch) {
case 'b': /* bootstrap file */
bsr = parse_bsr(NULL, optarg);
case 'e': /* exclude list */
if ((fd = fopen(optarg, "r")) == NULL) {
+ berrno be;
Pmsg2(0, "Could not open exclude file: %s, ERR=%s\n",
- optarg, strerror(errno));
+ optarg, be.strerror());
exit(1);
}
while (fgets(line, sizeof(line), fd) != NULL) {
case 'i': /* include list */
if ((fd = fopen(optarg, "r")) == NULL) {
+ berrno be;
Pmsg2(0, "Could not open include file: %s, ERR=%s\n",
- optarg, strerror(errno));
+ optarg, be.strerror());
exit(1);
}
while (fgets(line, sizeof(line), fd) != NULL) {
forge_on = true;
break;
+ case 'v':
+ verbose++;
+ break;
+
case 'V': /* Volume name */
VolumeName = optarg;
break;
static void do_extract(char *devname)
{
struct stat statp;
- jcr = setup_jcr("bextract", devname, bsr, VolumeName);
- dev = setup_to_access_device(jcr, 1); /* acquire for read */
+ jcr = setup_jcr("bextract", devname, bsr, VolumeName, 1); /* acquire for read */
+ if (!jcr) {
+ exit(1);
+ }
+ dev = jcr->dcr->dev;
if (!dev) {
exit(1);
}
/* Make sure where directory exists and that it is a directory */
if (stat(where, &statp) < 0) {
+ berrno be;
Emsg2(M_ERROR_TERM, 0, "Cannot stat %s. It must exist. ERR=%s\n",
- where, strerror(errno));
+ where, be.strerror());
}
if (!S_ISDIR(statp.st_mode)) {
Emsg1(M_ERROR_TERM, 0, "%s must be a directory.\n", where);
set_attributes(jcr, attr, &bfd);
}
release_device(jcr);
-
free_attr(attr);
- term_dev(dev);
free_jcr(jcr);
+ term_dev(dev);
+
printf("%u files restored.\n", num_files);
return;
}
/*
* Called here for each record from read_records()
*/
-static bool record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
+static bool record_cb(DCR *dcr, DEV_RECORD *rec)
{
int stat;
+ JCR *jcr = dcr->jcr;
if (rec->FileIndex < 0) {
return true; /* we don't want labels */
if (fileAddr != faddr) {
fileAddr = faddr;
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+ berrno be;
Emsg2(M_ERROR_TERM, 0, _("Seek error on %s: %s\n"),
- attr->ofname, strerror(errno));
+ attr->ofname, be.strerror());
}
}
} else {
total += wsize;
Dmsg2(8, "Write %u bytes, total=%u\n", wsize, total);
if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) {
+ berrno be;
Emsg2(M_ERROR_TERM, 0, _("Write error on %s: %s\n"),
- attr->ofname, strerror(errno));
+ attr->ofname, be.strerror());
}
fileAddr += wsize;
}
if (fileAddr != faddr) {
fileAddr = faddr;
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
+ berrno be;
Emsg3(M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
- edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
+ edit_uint64(fileAddr, ec1), attr->ofname, be.strerror());
extract = false;
return true;
}
Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total);
if ((uLongf)bwrite(&bfd, compress_buf, (size_t)compress_len) != compress_len) {
+ berrno be;
Pmsg0(0, "===Write error===\n");
Emsg2(M_ERROR, 0, _("Write error on %s: %s\n"),
- attr->ofname, strerror(errno));
+ attr->ofname, be.strerror());
extract = false;
return true;
}
bool dir_ask_sysop_to_mount_volume(DCR *dcr)
{
- JCR *jcr = dcr->jcr;
DEVICE *dev = dcr->dev;
fprintf(stderr, "Mount Volume \"%s\" on device %s and press return when ready: ",
- jcr->VolumeName, dev_name(dev));
+ dcr->VolumeName, dev_name(dev));
getchar();
return true;
}