- Test cancel at EOM.
- Test not zeroing Autochanger slot when it is wrong.
- Figure out how to use ssh or stunnel to protect Bacula communications.
-- Test connect timeouts.
For 1.33 Testing/Documentation:
-- Combine the 3 places that search run records for the next
- job. Use find_job_pool() modified in ua_output.c
+- Fix FreeBSD build with tcp_wrapper -- should not have -lnsl
- Document to start higher priorty jobs before lower ones.
- suppress "Do not forget to mount the drive!!!" if error
- Document new records in Director. SDAddress SDDeviceName, SDPassword.
- Add counter variable test.
For 1.33
+- Either restrict the characters in a name, or fix the problem
+ emailing with names containing / (smtp command line breaks).
+- Eliminate ua_retention.c (retentioncmd) if possible.
- Eliminate orphaned jobs: dbcheck, normal pruning, delete job command.
Hm. Well, there are the remaining orphaned job records:
2) add an option to the purge command to manually purge all jobs with
no associated volume.
+ I think Restore jobs also fall into category 2 above .... so one might
+ want to make that "The Job record has an EndTime,, but no associated
+ JobMedia record, and is not a Restore job."
+- Implement RestoreJobRetention? Maybe better "JobRetention" in a Job,
+ which would take precidence over the Catalog "JobRetention".
- Implement Label Format in Add and Label console commands.
- make "btape /tmp" work.
- Make sure a rescheduled job is properly reported by status.
- Document that it is safe to use the drive when the lights stop flashing.
- Document all the status codes JobLevel, JobType, JobStatus.
- Add GUI interface to manual
+- Combine the 3 places that search run records for the next
+ job. Use find_job_pool() modified in ua_output.c
+- Test connect timeouts.
+
/* Forward referenced functions */
static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd);
+void print_bsr(UAContext *ua, RBSR *bsr);
/*
* range regardless of volume. The FirstIndex and LastIndex
* passed in here are for the current volume, so when
* writing out the fi, constrain them to those values.
+ *
+ * We are called here once for each JobMedia record
+ * for each Volume.
*/
static void write_findex(UAContext *ua, RBSR_FINDEX *fi,
int32_t FirstIndex, int32_t LastIndex, FILE *fd)
{
- if (fi) {
+ for ( ; fi; fi=fi->next) {
int32_t findex, findex2;
- findex = fi->findex < FirstIndex ? FirstIndex : fi->findex;
- findex2 = fi->findex2 > LastIndex ? LastIndex : fi->findex2;
- if (findex == findex2) {
- fprintf(fd, "FileIndex=%d\n", findex);
- } else {
- fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
+ if ((fi->findex >= FirstIndex && fi->findex <= LastIndex) ||
+ (fi->findex2 >= FirstIndex && fi->findex2 <= LastIndex) ||
+ (fi->findex < FirstIndex && fi->findex2 > LastIndex)) {
+ findex = fi->findex < FirstIndex ? FirstIndex : fi->findex;
+ findex2 = fi->findex2 > LastIndex ? LastIndex : fi->findex2;
+ if (findex == findex2) {
+ fprintf(fd, "FileIndex=%d\n", findex);
+ } else {
+ fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
+ }
}
- write_findex(ua, fi->next, FirstIndex, LastIndex, fd);
}
}
static void print_findex(UAContext *ua, RBSR_FINDEX *fi)
{
- if (fi) {
+ bsendmsg(ua, "fi=0x%x\n", (unsigned)fi);
+ for ( ; fi; fi=fi->next) {
if (fi->findex == fi->findex2) {
bsendmsg(ua, "FileIndex=%d\n", fi->findex);
+// Dmsg1(000, "FileIndex=%d\n", fi->findex);
} else {
bsendmsg(ua, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
+// Dmsg2(000, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
}
- print_findex(ua, fi->next);
}
}
static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
{
if (bsr) {
+ /*
+ * For a given volume, loop over all the JobMedia records.
+ * VolCount is the number of JobMedia records.
+ */
for (int i=0; i < bsr->VolCount; i++) {
if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
bsr->VolParams[i].LastIndex)) {
}
}
-static void print_bsr(UAContext *ua, RBSR *bsr)
+void print_bsr(UAContext *ua, RBSR *bsr)
{
if (bsr) {
for (int i=0; i < bsr->VolCount; i++) {
}
/*
- * At this point, bsr points to bsr containing JobId,
+ * At this point, bsr points to bsr containing this JobId,
* and we are sure that there is at least one fi record.
*/
lfi = fi = bsr->fi;
if (findex == (fi->findex2 + 1)) { /* extend up */
RBSR_FINDEX *nfi;
fi->findex2 = findex;
+ /*
+ * If the following record contains one higher, merge its
+ * file index by extending it up.
+ */
if (fi->next && ((findex+1) == fi->next->findex)) {
nfi = fi->next;
fi->findex2 = nfi->findex2;
/* Imported functions */
extern int runcmd(UAContext *ua, char *cmd);
+extern void print_bsr(UAContext *ua, RBSR *bsr);
/* Imported variables */
extern char *uar_list_jobs, *uar_file, *uar_sel_files;
free_rx(&rx);
return 0;
}
-// print_bsr(ua, rx.bsr);
write_bsr_file(ua, rx.bsr);
bsendmsg(ua, _("\n%u file%s selected to restore.\n\n"), rx.selected_files,
rx.selected_files==1?"":"s");
if (!get_client_name(ua, rx)) {
return 0;
}
+ bsendmsg(ua, _("Enter file names, or < to enter a filename\n"
+ "containg a list of file names, and terminate\n"
+ "them with a blank line.\n"));
for ( ;; ) {
if (!get_cmd(ua, _("Enter filename: "))) {
return 0;
split_path_and_filename(rx, file);
Mmsg(&rx->query, uar_jobid_fileindex, rx->path, rx->fname, rx->ClientName);
rx->found = false;
+ /* Find and insert jobid and File Index */
if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) {
bsendmsg(ua, _("Query failed: %s. ERR=%s\n"),
rx->query, db_strerror(ua->db));
if (jcr->RestoreBootstrap) {
unlink(jcr->RestoreBootstrap);
free_pool_memory(jcr->RestoreBootstrap);
+ jcr->RestoreBootstrap = NULL;
}
if (jcr->last_fname) {
free_pool_memory(jcr->last_fname);
char buf[2000];
BSOCK *sd = jcr->store_bsock;
char *bootstrap = "bootstrap\n";
+ int stat = 0;
Dmsg1(400, "send_bootstrap_file: %s\n", jcr->RestoreBootstrap);
if (!jcr->RestoreBootstrap) {
Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
jcr->RestoreBootstrap, strerror(errno));
set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
+ goto bail_out;
}
pm_strcpy(&sd->msg, bootstrap);
sd->msglen = strlen(sd->msg);
fclose(bs);
if (!response(jcr, sd, OKSDbootstrap, "Bootstrap")) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
+ goto bail_out;
}
- return 1;
+ stat = 1;
+
+bail_out:
+ if (jcr->RestoreBootstrap) {
+ unlink(jcr->RestoreBootstrap);
+ free_pool_memory(jcr->RestoreBootstrap);
+ jcr->RestoreBootstrap = NULL;
+ }
+
+ return stat;
}
static char rec_header[] = "rechdr %ld %ld %ld %ld %ld";
/* Forward referenced functions */
+static char *zlib_strerror(int stat);
#define RETRY 10 /* retry wait time */
uint32_t size;
uint32_t VolSessionId, VolSessionTime;
int32_t file_index;
- int extract = FALSE;
+ bool extract = false;
BFILE bfd;
int stat;
uint32_t total = 0; /* Job total but only 32 bits for debug */
Jmsg0(jcr, M_ERROR, 0, _("Logic error output file should be open\n"));
}
set_attributes(jcr, attr, &bfd);
- extract = FALSE;
+ extract = false;
Dmsg0(30, "Stop extracting.\n");
}
jcr->num_files_examined++;
Dmsg1(30, "Outfile=%s\n", attr->ofname);
- extract = FALSE;
+ extract = false;
stat = create_file(jcr, attr, &bfd, jcr->replace);
switch (stat) {
case CF_ERROR:
case CF_SKIP:
break;
case CF_EXTRACT:
- extract = TRUE;
+ extract = true;
P(jcr->mutex);
pm_strcpy(&jcr->last_fname, attr->ofname);
V(jcr->mutex);
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
- extract = FALSE;
+ extract = false;
+ bclose(&bfd);
continue;
}
}
if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) {
Dmsg0(0, "===Write error===\n");
Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: ERR=%s\n"), attr->ofname, berror(&bfd));
- extract = FALSE;
+ extract = false;
+ bclose(&bfd);
continue;
}
total += wsize;
if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) {
Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"),
edit_uint64(fileAddr, ec1), attr->ofname, berror(&bfd));
- extract = FALSE;
+ extract = false;
+ bclose(&bfd);
continue;
}
}
Dmsg2(100, "Comp_len=%d msglen=%d\n", compress_len, wsize);
if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
(const Byte *)wbuf, (uLong)wsize)) != Z_OK) {
- Jmsg(jcr, M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
- extract = FALSE;
+ Jmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
+ attr->ofname, zlib_strerror(stat));
+ extract = false;
+ bclose(&bfd);
continue;
}
if ((uLong)bwrite(&bfd, jcr->compress_buf, compress_len) != compress_len) {
Dmsg0(0, "===Write error===\n");
Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), attr->ofname, berror(&bfd));
- extract = FALSE;
+ extract = false;
+ bclose(&bfd);
continue;
}
total += compress_len;
#else
if (extract) {
Jmsg(jcr, M_ERROR, 0, _("GZIP data stream found, but GZIP not configured!\n"));
- extract = FALSE;
+ extract = false;
+ bclose(&bfd);
continue;
}
#endif
Jmsg0(jcr, M_ERROR, 0, _("Logic error output file should be open but is not.\n"));
}
set_attributes(jcr, attr, &bfd);
- extract = FALSE;
+ extract = false;
}
Jmsg(jcr, M_ERROR, 0, _("Unknown stream=%d ignored. This shouldn't happen!\n"), stream);
Dmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
free(jcr->compress_buf);
jcr->compress_buf = NULL;
}
+ bclose(&bfd);
free_attr(attr);
Dmsg2(10, "End Do Restore. Files=%d Bytes=%" lld "\n", jcr->JobFiles,
jcr->JobBytes);
non_support_data, non_support_attr);
}
}
+
+/*
+ * Convert ZLIB error code into an ASCII message
+ */
+static char *zlib_strerror(int stat)
+{
+ if (stat >= 0) {
+ return "None";
+ }
+ switch (stat) {
+ case Z_ERRNO:
+ return "Zlib errno";
+ case Z_STREAM_ERROR:
+ return "Zlib stream error";
+ case Z_DATA_ERROR:
+ return "Zlib data error";
+ case Z_MEM_ERROR:
+ return "Zlib memory error";
+ case Z_BUF_ERROR:
+ return "Zlib buffer error";
+ case Z_VERSION_ERROR:
+ return "Zlib version error";
+ default:
+ return "*none*";
+ }
+}
if (is_bopen(ofd)) {
bclose(ofd);
}
+ pm_strcpy(&attr->ofname, "*none*");
return 1;
}
if (is_bopen(ofd)) {
bclose(ofd);
}
+ pm_strcpy(&attr->ofname, "*none*");
return 1;
}
/*
stat = 0;
}
}
+ pm_strcpy(&attr->ofname, "*none*");
umask(old_mask);
return stat;
}
{
int stat;
Dmsg1(50, "Close file %d\n", bfd->fid);
+ if (bfd->fid == -1) {
+ return 0;
+ }
stat = close(bfd->fid);
bfd->berrno = errno;
bfd->fid = -1;
Jmsg(jcr, M_INFO, 0, _("User defined maximum volume capacity %s exceeded on device %s.\n"),
edit_uint64(max_cap, ed1), dev->dev_name);
block->write_failed = true;
- weof_dev(dev, 2); /* end the tape */
+ weof_dev(dev, 1); /* end the tape */
+ weof_dev(dev, 1);
dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
return 0;
}
wlen, stat, dev->block_num, block->BlockNumber, dev->dev_errno, strerror(dev->dev_errno));
block->write_failed = true;
- if (weof_dev(dev, 2) != 0) { /* end the tape */
+ weof_dev(dev,1);
+ if (weof_dev(dev, 1) != 0) { /* end the tape */
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
}
dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
ssize_t stat;
int looping;
uint32_t BlockNumber;
- int retry = 0;
+ int retry;
if (dev_state(dev, ST_EOT)) {
return 0;
block->read_len = 0;
return 0;
}
+ retry = 0;
do {
stat = read(dev->fd, block->buf, (size_t)block->buf_len);
if (retry == 1) {
dev->VolCatInfo.VolCatErrors++;
}
} while (stat == -1 && (errno == EINTR || errno == EIO) && retry++ < 11);
+// Dmsg1(000, "read stat = %d\n", stat);
if (stat < 0) {
Dmsg1(90, "Read device got: ERR=%s\n", strerror(errno));
clrerror_dev(dev, -1);
*/
static void capcmd()
{
- printf(_("Device capabilities:\n"));
+ printf(_("Configured device capabilities:\n"));
printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
{
unsigned int i;
usage();
+ printf(_("Interactive commands:\n"));
printf(_(" Command Description\n ======= ===========\n"));
for (i=0; i<comsize; i++)
printf(" %-10s %s\n", commands[i].key, commands[i].help);
{
fprintf(stderr, _(
"\nVersion: " VERSION " (" BDATE ")\n\n"
-"Usage: btape [-c config_file] [-d debug_level] [device_name]\n"
+"Usage: btape [-c config_file] [-d debug_level] device_name\n"
" -c <file> set configuration file to file\n"
" -dnn set debug level to nn\n"
" -s turn off signals\n"
BSOCK *fd = jcr->file_bsock;
POOLMEM *fname = get_pool_memory(PM_FNAME);
FILE *bs;
+ int stat = 0;
if (jcr->RestoreBootstrap) {
unlink(jcr->RestoreBootstrap);
if (debug_level > 20) {
dump_bsr(jcr->bsr, true);
}
- return bnet_fsend(fd, OK_bootstrap);
+ stat = 1;
bail_out:
unlink(jcr->RestoreBootstrap);
free_pool_memory(jcr->RestoreBootstrap);
jcr->RestoreBootstrap = NULL;
- bnet_fsend(fd, ERROR_bootstrap);
- return 0;
-
+ if (stat) {
+ return bnet_fsend(fd, OK_bootstrap);
+ } else {
+ bnet_fsend(fd, ERROR_bootstrap);
+ return 0;
+ }
}
*/
ojcr = get_jcr_by_full_name(job);
if (ojcr && !ojcr->authenticated) {
- Dmsg2(000, "Found ojcr=0x%x Job %s\n", (unsigned)ojcr, job);
+ Dmsg2(100, "Found ojcr=0x%x Job %s\n", (unsigned)ojcr, job);
free_jcr(ojcr);
}
jcr->JobId = JobId;
return 1; /* cannot fast reject */
}
- if (match_block_sesstime(bsr, bsr->sesstime, block)) {
- return 1;
+ if (!match_block_sesstime(bsr, bsr->sesstime, block)) {
+ return 0;
}
return match_block_sessid(bsr, bsr->sessid, block);
}
if (bsr->done) {
goto no_match;
}
- if (bsr->count && bsr->count <= bsr->found) {
+ if (bsr->count && bsr->found >= bsr->count) {
bsr->done = true;
bsr->root->reposition = true;
Dmsg0(100, "bsr done from count\n");
#include "stored.h"
static void handle_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
+static BSR *position_to_first_file(JCR *jcr, DEVICE *dev);
#ifdef DEBUG
static char *rec_state_to_str(DEV_RECORD *rec);
#endif
block = new_block(dev);
recs = new dlist(rec, &rec->link);
+ position_to_first_file(jcr, dev);
for ( ; ok && !done; ) {
if (job_canceled(jcr)) {
break;
}
if (!read_block_from_device(jcr, dev, block, CHECK_BLOCK_NUMBERS)) {
- Dmsg0(20, "!read_record()\n");
if (dev_state(dev, ST_EOT)) {
DEV_RECORD *trec = new_record();
- Dmsg3(100, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
- block->BlockNumber, rec->remainder);
Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n",
dev->file, dev_name(dev), jcr->VolumeName);
if (!mount_cb(jcr, dev, block)) {
Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
- Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
- block->BlockNumber, rec->remainder);
ok = FALSE;
/*
* Create EOT Label so that Media record may
*/
trec->FileIndex = EOT_LABEL;
trec->File = dev->file;
- trec->Block = rec->Block; /* return block last read */
ok = record_cb(jcr, dev, block, trec);
free_record(trec);
break;
}
- Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
- block->BlockNumber, rec->remainder);
/*
* We just have a new tape up, now read the label (first record)
* and pass it off to the callback routine, then continue
handle_session_record(dev, trec, &sessrec);
ok = record_cb(jcr, dev, block, trec);
free_record(trec);
- /*
- * Now find and position to first file and block
- * on this tape.
- */
- if (jcr->bsr) {
- BSR *bsr;
-
- jcr->bsr->reposition = true;
- bsr = find_next_bsr(jcr->bsr, dev);
- if (bsr) {
- Jmsg(jcr, M_INFO, 0, _("Forward spacing to file:block %u:%u.\n"),
- bsr->volfile->sfile, bsr->volblock->sblock);
- Dmsg4(100, "Reposition new from (file:block) %d:%d to %d:%d\n",
- dev->file, dev->block_num, bsr->volfile->sfile,
- bsr->volblock->sblock);
- reposition_dev(dev, bsr->volfile->sfile, bsr->volblock->sblock);
- Dmsg2(100, "Now at (file:block) %d:%d\n",
- dev->file, dev->block_num);
- }
- }
+ position_to_first_file(jcr, dev);
/* After reading label, we must read first data block */
continue;
} else if (dev_state(dev, ST_EOF)) {
- Jmsg(jcr, M_INFO, 0, "Got EOF at file %u on device %s, Volume \"%s\"\n",
+ if (verbose) {
+ Jmsg(jcr, M_INFO, 0, "Got EOF at file %u on device %s, Volume \"%s\"\n",
dev->file, dev_name(dev), jcr->VolumeName);
- Dmsg0(20, "read_record got eof. try again\n");
+ }
continue;
} else if (dev_state(dev, ST_SHORT)) {
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
break;
}
}
- Dmsg5(100, "Read block: dev=%d blk=%d VI=%u VT=%u blen=%d\n", dev->block_num, block->BlockNumber,
+ Dmsg2(100, "New block at position=(file:block) %d:%d\n", dev->file, dev->block_num);
+ Dmsg5(100, "Read block: devblk=%d blk=%d VI=%u VT=%u blen=%d\n", dev->block_num, block->BlockNumber,
block->VolSessionId, block->VolSessionTime, block->block_len);
+#ifdef FAST_BLOCK_REJECTION
+ /* this does not stop when file/block are too big */
if (!match_bsr_block(jcr->bsr, block)) {
- Dmsg5(100, "reject Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
- block->BlockNumber, block->block_len, block->BlockVer,
- block->VolSessionId, block->VolSessionTime);
continue;
}
- Dmsg4(100, "Block: %d VI=%u VT=%u blen=%d\n", block->BlockNumber,
- block->VolSessionId, block->VolSessionTime, block->block_len);
+#endif
/*
* Get a new record for each Job as defined by
Dmsg2(100, "New record for SI=%d ST=%d\n",
block->VolSessionId, block->VolSessionTime);
} else {
+#ifdef xxx
if (rec->Block != 0 && (rec->Block+1) != block->BlockNumber) {
Jmsg(jcr, M_ERROR, 0, _("Invalid block number. Expected %u, got %u\n"),
rec->Block+1, block->BlockNumber);
}
+#endif
}
Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec),
block->BlockNumber, rec->remainder);
int stat = match_bsr(jcr->bsr, rec, &dev->VolHdr, &sessrec);
if (stat == -1) { /* no more possible matches */
done = true; /* all items found, stop */
+ Dmsg2(100, "All done=(file:block) %d:%d\n", dev->file, dev->block_num);
break;
} else if (stat == 0) { /* no match */
BSR *bsr;
Dmsg4(100, "Reposition from (file:block) %d:%d to %d:%d\n",
dev->file, dev->block_num, bsr->volfile->sfile,
bsr->volblock->sblock);
+ if (verbose) {
+ Jmsg(jcr, M_INFO, 0, "Reposition from (file:block) %d:%d to %d:%d\n",
+ dev->file, dev->block_num, bsr->volfile->sfile,
+ bsr->volblock->sblock);
+ }
reposition_dev(dev, bsr->volfile->sfile, bsr->volblock->sblock);
rec->Block = 0;
Dmsg2(100, "Now at (file:block) %d:%d\n",
ok = record_cb(jcr, dev, block, rec);
} /* end for loop over records */
} /* end for loop over blocks */
+ Dmsg2(100, "Position=(file:block) %d:%d\n", dev->file, dev->block_num);
/* Walk down list and free all remaining allocated recs */
for (rec=(DEV_RECORD *)recs->first(); rec; ) {
return ok;
}
+static BSR *position_to_first_file(JCR *jcr, DEVICE *dev)
+{
+ BSR *bsr = NULL;
+ /*
+ * Now find and position to first file and block
+ * on this tape.
+ */
+ if (jcr->bsr) {
+ jcr->bsr->reposition = true;
+ bsr = find_next_bsr(jcr->bsr, dev);
+ if (bsr) {
+ Jmsg(jcr, M_INFO, 0, _("Forward spacing to file:block %u:%u.\n"),
+ bsr->volfile->sfile, bsr->volblock->sblock);
+ Dmsg4(100, "Reposition new from (file:block) %d:%d to %d:%d\n",
+ dev->file, dev->block_num, bsr->volfile->sfile,
+ bsr->volblock->sblock);
+ reposition_dev(dev, bsr->volfile->sfile, bsr->volblock->sblock);
+ Dmsg2(100, "Now at (file:block) %d:%d\n",
+ dev->file, dev->block_num);
+ }
+ }
+ return bsr;
+}
+
static void handle_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
{
/* */
-#undef VERSION
-#define VERSION "1.32a"
+#undef VERSION
+#define VERSION "1.32b"
#define VSTRING "1"
-#define BDATE "04 Oct 2003"
-#define LSMDATE "04Oct03"
+#define BDATE "08 Oct 2003"
+#define LSMDATE "08Oct03"
/* Debug flags */
-#undef DEBUG
+#undef DEBUG
#define DEBUG 1
#define TRACEBACK 1
#define SMCHECK