Kern's ToDo List
- 12 June 2005
+ 16 June 2005
Major development:
Project Developer
- Document the multiple-drive-changer.txt script.
For 1.37:
+- Add # Job Level date to bsr file
- Implement "PreferMountedVolumes = yes|no" in Job resource.
=== rate design
jcr->last_rate
General:
+Changes to 1.37.24:
+16Jun05
+- Add Date, Job, level to updates to .bsr file in
+ dird/backup.c
+- Add debug info to dvd-freespace.in
+- Fix hard coded bacula.sql in make_catalog_backup reported
+ by a user.
+- Make sure a verify volume to catalog never reports an error
+ if there are zero files to verify.
+- Remove confusing debug info in filed/backup.c on network
+ error.
+- Make sure output from console is not sent to system log.
+- Convert open_dev() into a class method.
+- Change VolHdr.VolName to VolHdr.VolumeName.
+- Add a flag in the device state word to indicate that
+ we found Media in the drive (DVD).
+- Make mount_dev() and unmount_dev() return bool.
+
+Changes to 1.37.23:
+- Renamed to make unique version for open_next_part()
+ changes.
+
Changes to 1.37.22:
14Jun05
- Fix the same state variable problem in open_next_part().
# Should always exit with 0 status, otherwise it indicates a serious error.
# (wrong number of arguments, Python exception...)
#
+# called: dvd-freespace <dvd-device-name> <part-number>
+#
+#
+# returns:
# Prints on the first output line the free space available in bytes.
# If an error occurs, prints a negative number (-errno), followed,
# on the second line, by an error message.
status = processi.wait()
if not os.WIFEXITED(status):
print -errno.EPIPE
- print "Process has not exited correctly."
+ print dvdrwmediainfo + " process did not exit correctly."
sys.exit(0)
if os.WEXITSTATUS(status) != 0:
print -errno.EPIPE
while 1:
result = processi.fromchild.readline()
if result.find("Legacy lead-out at:") > -1:
- index = result.find("=")
- if index > -1:
- res = result[index+1:-1]
- if not res.isdigit():
- print -errno.EPIPE
- print 'Invalid format in media info lead-out line.'
- sys.exit(0)
- return int(res)
- else:
- print -errno.EPIPE
- print 'Invalid format in media info lead-out line.'
- sys.exit(0)
+ index = result.find("=")
+ if index > -1:
+ res = result[index+1:-1]
+ if not res.isdigit():
+ print -errno.EPIPE
+ print "Invalid format in media info lead-out line from " + dvdrwmediainfo
+ sys.exit(0)
+ return int(res)
+ else:
+ print -errno.EPIPE
+ print "Invalid format in media info lead-out line from " + dvdrwmediainfo
+ sys.exit(0)
if not result:
- print -errno.EPIPE
- print 'Cannot get media lead-out index.'
- sys.exit(0)
+ print -errno.EPIPE
+ print "Cannot get media lead-out index from " + dvdrwmediainfo
+ sys.exit(0)
tmpfile = tempfile.NamedTemporaryFile()
if part_num == 0:
status = process.wait()
if not os.WIFEXITED(status):
print -errno.EPIPE
- print "Process has not exited correctly."
+ print growisofs + " process did not not exit correctly."
sys.exit(0)
exitstat = os.WEXITSTATUS(status) & ~0x80
result = process.fromchild.readline()
if not result:
print -errno.EPIPE
- print 'Cannot find the seek argument in the output.'
+ print "Cannot find the seek argument in the output from " + growisofs
sys.exit(0)
index = result.find("seek=")
if index > -1:
res = result[index+5:-2]
if not res.isdigit():
- print -errno.EPIPE
- print 'Wrong seek argument in the output.'
- sys.exit(0)
+ print -errno.EPIPE
+ print "Wrong seek argument in the output from " + growisofs
+ sys.exit(0)
size = int(res)*32*1024
size = gettotalsize()-(size+margin)
if size < 0:
- size = 0
+ size = 0
print size
print "No error occured"
sys.exit(0)
#
#
cd @working_dir@
-rm -f bacula.sql
+rm -f $1.sql
if test xsqlite = x@DB_NAME@ ; then
echo ".dump" | @SQL_BINDIR@/sqlite $1.db >$1.sql
else
}
}
+ /* Start output with when and who wrote it */
+ bstrftimes(edt, sizeof(edt), time(NULL));
+ fprintf(fd, "# %s - %s - %s%s\n", edt, jcr->jr.Job,
+ level_to_str(jcr->JobLevel), jcr->since);
for (int i=0; i < VolCount; i++) {
/* Write the record */
fprintf(fd, "Volume=\"%s\"\n", VolParams[i].VolumeName);
/*
* delete_job has been modified to parse JobID lists like the
* following:
- * delete job JobID=3,4,6,7-11,14
+ * delete JobID=3,4,6,7-11,14
*
* Thanks to Phil Stracchino for the above addition.
*/
* Basic tasks done here:
* Open DB
* Open connection with File daemon and pass him commands
- * to do the verify.
+ * to do the verify.
* When the File daemon sends the attributes, compare them to
- * what is in the DB.
+ * what is in the DB.
*
* Version $Id$
*/
Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
/*
- * Find JobId of last job that ran. E.g.
- * for VERIFY_CATALOG we want the JobId of the last INIT.
- * for VERIFY_VOLUME_TO_CATALOG, we want the JobId of the
- * last backup Job.
+ * Find JobId of last job that ran. E.g.
+ * for VERIFY_CATALOG we want the JobId of the last INIT.
+ * for VERIFY_VOLUME_TO_CATALOG, we want the JobId of the
+ * last backup Job.
*/
if (jcr->JobLevel == L_VERIFY_CATALOG ||
jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG) {
memcpy(&jr, &jcr->jr, sizeof(jr));
if (jcr->verify_job &&
- (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
- jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG)) {
- Name = jcr->verify_job->hdr.name;
+ (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
+ jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG)) {
+ Name = jcr->verify_job->hdr.name;
} else {
- Name = NULL;
+ Name = NULL;
}
Dmsg1(100, "find last jobid for: %s\n", NPRT(Name));
if (!db_find_last_jobid(jcr, jcr->db, Name, &jr)) {
- if (jcr->JobLevel == L_VERIFY_CATALOG) {
- Jmsg(jcr, M_FATAL, 0, _(
+ if (jcr->JobLevel == L_VERIFY_CATALOG) {
+ Jmsg(jcr, M_FATAL, 0, _(
"Unable to find JobId of previous InitCatalog Job.\n"
"Please run a Verify with Level=InitCatalog before\n"
"running the current Job.\n"));
- } else {
- Jmsg(jcr, M_FATAL, 0, _(
+ } else {
+ Jmsg(jcr, M_FATAL, 0, _(
"Unable to find JobId of previous Job for this client.\n"));
- }
- return false;
+ }
+ return false;
}
verify_jobid = jr.JobId;
Dmsg1(100, "Last full jobid=%d\n", verify_jobid);
}
/*
* Now get the job record for the previous backup that interests
- * us. We use the verify_jobid that we found above.
+ * us. We use the verify_jobid that we found above.
*/
if (jcr->JobLevel == L_VERIFY_CATALOG ||
jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
jcr->target_jr.JobId = verify_jobid;
if (!db_get_job_record(jcr, jcr->db, &jcr->target_jr)) {
Jmsg(jcr, M_FATAL, 0, _("Could not get job record for previous Job. ERR=%s"),
- db_strerror(jcr->db));
- return false;
+ db_strerror(jcr->db));
+ return false;
}
if (jcr->target_jr.JobStatus != 'T') {
Jmsg(jcr, M_FATAL, 0, _("Last Job %d did not terminate normally. JobStatus=%c\n"),
- verify_jobid, jcr->target_jr.JobStatus);
- return false;
+ verify_jobid, jcr->target_jr.JobStatus);
+ return false;
}
Jmsg(jcr, M_INFO, 0, _("Verifying against JobId=%d Job=%s\n"),
- jcr->target_jr.JobId, jcr->target_jr.Job);
+ jcr->target_jr.JobId, jcr->target_jr.Job);
}
/*
* If we are verifying a Volume, we need the Storage
- * daemon, so open a connection, otherwise, just
- * create a dummy authorization key (passed to
- * File daemon but not used).
+ * daemon, so open a connection, otherwise, just
+ * create a dummy authorization key (passed to
+ * File daemon but not used).
*/
if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) {
RBSR *bsr = new_bsr();
bsr->fi->findex2 = jcr->target_jr.JobFiles;
jcr->ExpectedFiles = write_bsr_file(ua, bsr);
if (jcr->ExpectedFiles == 0) {
- free_ua_context(ua);
- free_bsr(bsr);
- return false;
+ free_ua_context(ua);
+ free_bsr(bsr);
+ return false;
}
if (jcr->RestoreBootstrap) {
- free(jcr->RestoreBootstrap);
+ free(jcr->RestoreBootstrap);
}
POOLMEM *fname = get_pool_memory(PM_MESSAGE);
make_unique_restore_filename(ua, &fname);
* Do a verification of the specified files against the Catlaog
*
* Returns: false on failure
- * true on success
+ * true on success
*/
bool do_verify(JCR *jcr)
{
*/
set_jcr_job_status(jcr, JS_Blocked);
if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
- return false;
+ return false;
}
/*
* Now start a job with the Storage daemon
*/
if (!start_storage_daemon_job(jcr, jcr->storage, SD_READ)) {
- return false;
+ return false;
}
/*
* Now start a Storage daemon message thread
*/
if (!start_storage_daemon_message_thread(jcr)) {
- return false;
+ return false;
}
Dmsg0(50, "Storage daemon connection OK\n");
}
/*
* Send Level command to File daemon, as well
- * as the Storage address if appropriate.
+ * as the Storage address if appropriate.
*/
switch (jcr->JobLevel) {
case L_VERIFY_INIT:
* send Storage daemon address to the File daemon
*/
if (jcr->store->SDDport == 0) {
- jcr->store->SDDport = jcr->store->SDport;
+ jcr->store->SDDport = jcr->store->SDport;
}
bnet_fsend(fd, storaddr, jcr->store->address, jcr->store->SDDport);
if (!response(jcr, fd, OKstore, "Storage", DISPLAY_ERROR)) {
- return false;
+ return false;
}
/*
* Send the bootstrap file -- what Volumes/files to restore
*/
if (!send_bootstrap_file(jcr)) {
- return false;
+ return false;
}
if (!jcr->RestoreBootstrap) {
Jmsg0(jcr, M_FATAL, 0, _("Deprecated feature ... use bootstrap.\n"));
- return false;
+ return false;
}
level = "volume";
break;
default:
Jmsg2(jcr, M_FATAL, 0, _("Unimplemented Verify level %d(%c)\n"), jcr->JobLevel,
- jcr->JobLevel);
+ jcr->JobLevel);
return false;
}
switch (jcr->JobLevel) {
case L_VERIFY_CATALOG:
Dmsg0(10, "Verify level=catalog\n");
- jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */
+ jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */
jcr->SDJobStatus = JS_Terminated;
get_attributes_and_compare_to_catalog(jcr, jcr->target_jr.JobId);
break;
case L_VERIFY_DISK_TO_CATALOG:
Dmsg0(10, "Verify level=disk_to_catalog\n");
- jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */
+ jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */
jcr->SDJobStatus = JS_Terminated;
get_attributes_and_compare_to_catalog(jcr, jcr->target_jr.JobId);
break;
case L_VERIFY_INIT:
/* Build catalog */
Dmsg0(10, "Verify level=init\n");
- jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */
+ jcr->sd_msg_thread_done = true; /* no SD msg thread, so it is done */
jcr->SDJobStatus = JS_Terminated;
get_attributes_and_put_in_catalog(jcr);
break;
const char *Name;
// Dmsg1(100, "Enter verify_cleanup() TermCod=%d\n", TermCode);
- dequeue_messages(jcr); /* display any queued messages */
+ dequeue_messages(jcr); /* display any queued messages */
Dmsg3(900, "JobLevel=%c Expected=%u JobFiles=%u\n", jcr->JobLevel,
jcr->ExpectedFiles, jcr->JobFiles);
TermCode = JS_ErrorTerminated;
}
+ /* If no files were expected, there can be no error */
+ if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG &&
+ jcr->ExpectedFiles == 0) {
+ TermCode = JS_Terminated;
+ }
+
JobId = jcr->jr.JobId;
set_jcr_job_status(jcr, TermCode);
jcr->unlink_bsr = false;
}
- msg_type = M_INFO; /* by default INFO message */
+ msg_type = M_INFO; /* by default INFO message */
switch (TermCode) {
case JS_Terminated:
term_msg = _("Verify OK");
case JS_FatalError:
case JS_ErrorTerminated:
term_msg = _("*** Verify Error ***");
- msg_type = M_ERROR; /* Generate error message */
+ msg_type = M_ERROR; /* Generate error message */
break;
case JS_Error:
term_msg = _("Verify warnings");
" FD termination status: %s\n"
" SD termination status: %s\n"
" Termination: %s\n\n"),
- edt,
- jcr->jr.JobId,
- jcr->jr.Job,
- jcr->fileset->hdr.name,
- level_to_str(jcr->JobLevel),
- jcr->client->hdr.name,
- jcr->target_jr.JobId,
- Name,
- sdt,
- edt,
- edit_uint64_with_commas(jcr->ExpectedFiles, ec1),
- edit_uint64_with_commas(jcr->JobFiles, ec2),
- jcr->Errors,
- fd_term_msg,
- sd_term_msg,
- term_msg);
+ edt,
+ jcr->jr.JobId,
+ jcr->jr.Job,
+ jcr->fileset->hdr.name,
+ level_to_str(jcr->JobLevel),
+ jcr->client->hdr.name,
+ jcr->target_jr.JobId,
+ Name,
+ sdt,
+ edt,
+ edit_uint64_with_commas(jcr->ExpectedFiles, ec1),
+ edit_uint64_with_commas(jcr->JobFiles, ec2),
+ jcr->Errors,
+ fd_term_msg,
+ sd_term_msg,
+ term_msg);
} else {
Jmsg(jcr, msg_type, 0, _("Bacula " VERSION " (" LSMDATE "): %s\n"
" JobId: %d\n"
" Non-fatal FD errors: %d\n"
" FD termination status: %s\n"
" Termination: %s\n\n"),
- edt,
- jcr->jr.JobId,
- jcr->jr.Job,
- jcr->fileset->hdr.name,
- level_to_str(jcr->JobLevel),
- jcr->client->hdr.name,
- jcr->target_jr.JobId,
- Name,
- sdt,
- edt,
- edit_uint64_with_commas(jcr->JobFiles, ec1),
- jcr->Errors,
- fd_term_msg,
- term_msg);
+ edt,
+ jcr->jr.JobId,
+ jcr->jr.Job,
+ jcr->fileset->hdr.name,
+ level_to_str(jcr->JobLevel),
+ jcr->client->hdr.name,
+ jcr->target_jr.JobId,
+ Name,
+ sdt,
+ edt,
+ edit_uint64_with_commas(jcr->JobFiles, ec1),
+ jcr->Errors,
+ fd_term_msg,
+ term_msg);
}
Dmsg0(100, "Leave verify_cleanup()\n");
}
BSOCK *fd;
int n, len;
FILE_DBR fdbr;
- struct stat statf; /* file stat */
- struct stat statc; /* catalog stat */
+ struct stat statf; /* file stat */
+ struct stat statc; /* catalog stat */
int stat = JS_Terminated;
char buf[MAXSTRING];
POOLMEM *fname = get_pool_memory(PM_MESSAGE);
/*
* Get Attributes and Signature from File daemon
* We expect:
- * FileIndex
- * Stream
- * Options or SIG (MD5/SHA1)
- * Filename
- * Attributes
- * Link name ???
+ * FileIndex
+ * Stream
+ * Options or SIG (MD5/SHA1)
+ * Filename
+ * Attributes
+ * Link name ???
*/
while ((n=bget_dirmsg(fd)) >= 0 && !job_canceled(jcr)) {
int stream;
jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen);
Dmsg1(200, "Atts+SIG=%s\n", fd->msg);
if ((len = sscanf(fd->msg, "%ld %d %100s", &file_index, &stream,
- fname)) != 3) {
+ fname)) != 3) {
Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 3 fields got %d\n"
" mslen=%d msg=%s\n"), len, fd->msglen, fd->msg);
- return false;
+ return false;
}
/*
* We read the Options or Signature into fname
*/
bstrncpy(Opts_SIG, fname, sizeof(Opts_SIG));
p = fd->msg;
- skip_nonspaces(&p); /* skip FileIndex */
+ skip_nonspaces(&p); /* skip FileIndex */
skip_spaces(&p);
- skip_nonspaces(&p); /* skip Stream */
+ skip_nonspaces(&p); /* skip Stream */
skip_spaces(&p);
- skip_nonspaces(&p); /* skip Opts_SIG */
- p++; /* skip space */
+ skip_nonspaces(&p); /* skip Opts_SIG */
+ p++; /* skip space */
fn = fname;
while (*p != 0) {
- *fn++ = *p++; /* copy filename */
+ *fn++ = *p++; /* copy filename */
}
- *fn = *p++; /* term filename and point to attribs */
+ *fn = *p++; /* term filename and point to attribs */
attr = p;
/*
* Got attributes stream, decode it
*/
if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX) {
- int32_t LinkFIf, LinkFIc;
+ int32_t LinkFIf, LinkFIc;
Dmsg2(400, "file_index=%d attr=%s\n", file_index, attr);
- jcr->JobFiles++;
- jcr->FileIndex = file_index; /* remember attribute file_index */
- decode_stat(attr, &statf, &LinkFIf); /* decode file stat packet */
- do_SIG = NO_SIG;
- jcr->fn_printed = false;
- pm_strcpy(jcr->fname, fname); /* move filename into JCR */
+ jcr->JobFiles++;
+ jcr->FileIndex = file_index; /* remember attribute file_index */
+ decode_stat(attr, &statf, &LinkFIf); /* decode file stat packet */
+ do_SIG = NO_SIG;
+ jcr->fn_printed = false;
+ pm_strcpy(jcr->fname, fname); /* move filename into JCR */
Dmsg2(040, "dird<filed: stream=%d %s\n", stream, jcr->fname);
Dmsg1(020, "dird<filed: attr=%s\n", attr);
- /*
- * Find equivalent record in the database
- */
- fdbr.FileId = 0;
- if (!db_get_file_attributes_record(jcr, jcr->db, jcr->fname,
- &jcr->target_jr, &fdbr)) {
+ /*
+ * Find equivalent record in the database
+ */
+ fdbr.FileId = 0;
+ if (!db_get_file_attributes_record(jcr, jcr->db, jcr->fname,
+ &jcr->target_jr, &fdbr)) {
Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname);
- stat = JS_Differences;
- continue;
- } else {
- /*
- * mark file record as visited by stuffing the
- * current JobId, which is unique, into the MarkId field.
- */
- db_mark_file_record(jcr, jcr->db, fdbr.FileId, jcr->JobId);
- }
+ stat = JS_Differences;
+ continue;
+ } else {
+ /*
+ * mark file record as visited by stuffing the
+ * current JobId, which is unique, into the MarkId field.
+ */
+ db_mark_file_record(jcr, jcr->db, fdbr.FileId, jcr->JobId);
+ }
Dmsg3(400, "Found %s in catalog. inx=%d Opts=%s\n", jcr->fname,
- file_index, Opts_SIG);
- decode_stat(fdbr.LStat, &statc, &LinkFIc); /* decode catalog stat */
- /*
- * Loop over options supplied by user and verify the
- * fields he requests.
- */
- for (p=Opts_SIG; *p; p++) {
- char ed1[30], ed2[30];
- switch (*p) {
+ file_index, Opts_SIG);
+ decode_stat(fdbr.LStat, &statc, &LinkFIc); /* decode catalog stat */
+ /*
+ * Loop over options supplied by user and verify the
+ * fields he requests.
+ */
+ for (p=Opts_SIG; *p; p++) {
+ char ed1[30], ed2[30];
+ switch (*p) {
case 'i': /* compare INODEs */
- if (statc.st_ino != statf.st_ino) {
- prt_fname(jcr);
+ if (statc.st_ino != statf.st_ino) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_ino differ. Cat: %s File: %s\n"),
- edit_uint64((uint64_t)statc.st_ino, ed1),
- edit_uint64((uint64_t)statf.st_ino, ed2));
- stat = JS_Differences;
- }
- break;
+ edit_uint64((uint64_t)statc.st_ino, ed1),
+ edit_uint64((uint64_t)statf.st_ino, ed2));
+ stat = JS_Differences;
+ }
+ break;
case 'p': /* permissions bits */
- if (statc.st_mode != statf.st_mode) {
- prt_fname(jcr);
+ if (statc.st_mode != statf.st_mode) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_mode differ. Cat: %x File: %x\n"),
- (uint32_t)statc.st_mode, (uint32_t)statf.st_mode);
- stat = JS_Differences;
- }
- break;
+ (uint32_t)statc.st_mode, (uint32_t)statf.st_mode);
+ stat = JS_Differences;
+ }
+ break;
case 'n': /* number of links */
- if (statc.st_nlink != statf.st_nlink) {
- prt_fname(jcr);
+ if (statc.st_nlink != statf.st_nlink) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_nlink differ. Cat: %d File: %d\n"),
- (uint32_t)statc.st_nlink, (uint32_t)statf.st_nlink);
- stat = JS_Differences;
- }
- break;
+ (uint32_t)statc.st_nlink, (uint32_t)statf.st_nlink);
+ stat = JS_Differences;
+ }
+ break;
case 'u': /* user id */
- if (statc.st_uid != statf.st_uid) {
- prt_fname(jcr);
+ if (statc.st_uid != statf.st_uid) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_uid differ. Cat: %u File: %u\n"),
- (uint32_t)statc.st_uid, (uint32_t)statf.st_uid);
- stat = JS_Differences;
- }
- break;
+ (uint32_t)statc.st_uid, (uint32_t)statf.st_uid);
+ stat = JS_Differences;
+ }
+ break;
case 'g': /* group id */
- if (statc.st_gid != statf.st_gid) {
- prt_fname(jcr);
+ if (statc.st_gid != statf.st_gid) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_gid differ. Cat: %u File: %u\n"),
- (uint32_t)statc.st_gid, (uint32_t)statf.st_gid);
- stat = JS_Differences;
- }
- break;
+ (uint32_t)statc.st_gid, (uint32_t)statf.st_gid);
+ stat = JS_Differences;
+ }
+ break;
case 's': /* size */
- if (statc.st_size != statf.st_size) {
- prt_fname(jcr);
+ if (statc.st_size != statf.st_size) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_size differ. Cat: %s File: %s\n"),
- edit_uint64((uint64_t)statc.st_size, ed1),
- edit_uint64((uint64_t)statf.st_size, ed2));
- stat = JS_Differences;
- }
- break;
+ edit_uint64((uint64_t)statc.st_size, ed1),
+ edit_uint64((uint64_t)statf.st_size, ed2));
+ stat = JS_Differences;
+ }
+ break;
case 'a': /* access time */
- if (statc.st_atime != statf.st_atime) {
- prt_fname(jcr);
+ if (statc.st_atime != statf.st_atime) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_atime differs\n"));
- stat = JS_Differences;
- }
- break;
+ stat = JS_Differences;
+ }
+ break;
case 'm':
- if (statc.st_mtime != statf.st_mtime) {
- prt_fname(jcr);
+ if (statc.st_mtime != statf.st_mtime) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_mtime differs\n"));
- stat = JS_Differences;
- }
- break;
+ stat = JS_Differences;
+ }
+ break;
case 'c': /* ctime */
- if (statc.st_ctime != statf.st_ctime) {
- prt_fname(jcr);
+ if (statc.st_ctime != statf.st_ctime) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_ctime differs\n"));
- stat = JS_Differences;
- }
- break;
+ stat = JS_Differences;
+ }
+ break;
case 'd': /* file size decrease */
- if (statc.st_size > statf.st_size) {
- prt_fname(jcr);
+ if (statc.st_size > statf.st_size) {
+ prt_fname(jcr);
Jmsg(jcr, M_INFO, 0, _(" st_size decrease. Cat: %s File: %s\n"),
- edit_uint64((uint64_t)statc.st_size, ed1),
- edit_uint64((uint64_t)statf.st_size, ed2));
- stat = JS_Differences;
- }
- break;
+ edit_uint64((uint64_t)statc.st_size, ed1),
+ edit_uint64((uint64_t)statf.st_size, ed2));
+ stat = JS_Differences;
+ }
+ break;
case '5': /* compare MD5 */
Dmsg1(500, "set Do_MD5 for %s\n", jcr->fname);
- do_SIG = MD5_SIG;
- break;
+ do_SIG = MD5_SIG;
+ break;
case '1': /* compare SHA1 */
- do_SIG = SHA1_SIG;
- break;
+ do_SIG = SHA1_SIG;
+ break;
case ':':
case 'V':
- default:
- break;
- }
- }
+ default:
+ break;
+ }
+ }
/*
* Got SIG Signature from Storage daemon
* It came across in the Opts_SIG field.
*/
} else if (stream == STREAM_MD5_SIGNATURE || stream == STREAM_SHA1_SIGNATURE) {
Dmsg2(400, "stream=SIG inx=%d SIG=%s\n", file_index, Opts_SIG);
- /*
- * When ever we get a signature is MUST have been
- * preceded by an attributes record, which sets attr_file_index
- */
- if (jcr->FileIndex != (uint32_t)file_index) {
+ /*
+ * When ever we get a signature is MUST have been
+ * preceded by an attributes record, which sets attr_file_index
+ */
+ if (jcr->FileIndex != (uint32_t)file_index) {
Jmsg2(jcr, M_FATAL, 0, _("MD5/SHA1 index %d not same as attributes %d\n"),
- file_index, jcr->FileIndex);
- return false;
- }
- if (do_SIG) {
- db_escape_string(buf, Opts_SIG, strlen(Opts_SIG));
- if (strcmp(buf, fdbr.SIG) != 0) {
- prt_fname(jcr);
- if (debug_level >= 10) {
+ file_index, jcr->FileIndex);
+ return false;
+ }
+ if (do_SIG) {
+ db_escape_string(buf, Opts_SIG, strlen(Opts_SIG));
+ if (strcmp(buf, fdbr.SIG) != 0) {
+ prt_fname(jcr);
+ if (debug_level >= 10) {
Jmsg(jcr, M_INFO, 0, _(" %s not same. File=%s Cat=%s\n"),
stream==STREAM_MD5_SIGNATURE?"MD5":"SHA1", buf, fdbr.SIG);
- } else {
+ } else {
Jmsg(jcr, M_INFO, 0, _(" %s differs.\n"),
stream==STREAM_MD5_SIGNATURE?"MD5":"SHA1");
- }
- stat = JS_Differences;
- }
- do_SIG = FALSE;
- }
+ }
+ stat = JS_Differences;
+ }
+ do_SIG = FALSE;
+ }
}
jcr->JobFiles = file_index;
}
if (is_bnet_error(fd)) {
berrno be;
Jmsg2(jcr, M_FATAL, 0, _("bdird<filed: bad attributes from filed n=%d : %s\n"),
- n, be.strerror());
+ n, be.strerror());
return false;
}
}
sd->msg = wbuf; /* set correct write buffer */
if (!bnet_send(sd)) {
- Jmsg2(jcr, M_FATAL, 0, _("Network send error %d to SD. ERR=%s\n"),
- sd->msglen, bnet_strerror(sd));
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ bnet_strerror(sd));
sd->msg = msgsave; /* restore bnet buffer */
sd->msglen = 0;
return 0;
*
*/
/*
- Copyright (C) 2000-2005 Kern Sibbald
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
+ modify it under the terms of the GNU General Public License
+ version 2 as ammended 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 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., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional details.
*/
* Start a timer on a child process of pid, kill it after wait seconds.
*
* Returns: btimer_t *(pointer to btimer_t struct) on success
- * NULL on failure
+ * NULL on failure
*/
btimer_t *start_child_timer(pid_t pid, uint32_t wait)
{
wid->wd->interval = wait;
register_watchdog(wid->wd);
- Dmsg3(200, "Start child timer %p, pid %d for %d secs.\n", wid, pid, wait);
+ Dmsg3(900, "Start child timer %p, pid %d for %d secs.\n", wid, pid, wait);
return wid;
}
void stop_child_timer(btimer_t *wid)
{
if (wid == NULL) {
- Dmsg0(200, "stop_child_timer called with NULL btimer_id\n");
+ Dmsg0(900, "stop_child_timer called with NULL btimer_id\n");
return;
}
- Dmsg2(200, "Stop child timer %p pid %d\n", wid, wid->pid);
+ Dmsg2(900, "Stop child timer %p pid %d\n", wid, wid->pid);
stop_btimer(wid);
}
* Start a timer on a thread. kill it after wait seconds.
*
* Returns: btimer_t *(pointer to btimer_t struct) on success
- * NULL on failure
+ * NULL on failure
*/
btimer_t *start_thread_timer(pthread_t tid, uint32_t wait)
{
btimer_t *wid;
wid = btimer_start_common(wait);
if (wid == NULL) {
- Dmsg1(200, "start_thread_timer return NULL from common. wait=%d.\n", wait);
+ Dmsg1(900, "start_thread_timer return NULL from common. wait=%d.\n", wait);
return NULL;
}
wid->type = TYPE_PTHREAD;
wid->wd->interval = wait;
register_watchdog(wid->wd);
- Dmsg3(200, "Start thread timer %p tid %p for %d secs.\n", wid, tid, wait);
+ Dmsg3(900, "Start thread timer %p tid %p for %d secs.\n", wid, tid, wait);
return wid;
}
* Start a timer on a BSOCK. kill it after wait seconds.
*
* Returns: btimer_t *(pointer to btimer_t struct) on success
- * NULL on failure
+ * NULL on failure
*/
btimer_t *start_bsock_timer(BSOCK *bsock, uint32_t wait)
{
register_watchdog(wid->wd);
Dmsg4(50, "Start bsock timer %p tid=%p for %d secs at %d\n", wid,
- wid->tid, wait, time(NULL));
+ wid->tid, wait, time(NULL));
return wid;
}
void stop_bsock_timer(btimer_t *wid)
{
if (wid == NULL) {
- Dmsg0(200, "stop_bsock_timer called with NULL btimer_id\n");
+ Dmsg0(900, "stop_bsock_timer called with NULL btimer_id\n");
return;
}
Dmsg3(50, "Stop bsock timer %p tid=%p at %d.\n", wid, wid->tid, time(NULL));
void stop_thread_timer(btimer_t *wid)
{
if (wid == NULL) {
- Dmsg0(200, "stop_thread_timer called with NULL btimer_id\n");
+ Dmsg0(900, "stop_thread_timer called with NULL btimer_id\n");
return;
}
- Dmsg2(200, "Stop thread timer %p tid=%p.\n", wid, wid->tid);
+ Dmsg2(900, "Stop thread timer %p tid=%p.\n", wid, wid->tid);
stop_btimer(wid);
}
if (msg == NULL) {
daemon_msgs = (MSGS *)malloc(sizeof(MSGS));
memset(daemon_msgs, 0, sizeof(MSGS));
- for (i=1; i<=M_MAX; i++) {
#ifndef WIN32
+ for (i=1; i<=M_MAX; i++) {
add_msg_dest(daemon_msgs, MD_STDOUT, i, NULL, NULL);
-#endif
- add_msg_dest(daemon_msgs, MD_SYSLOG, i, NULL, NULL);
}
+#endif
Dmsg1(050, "Create daemon global message resource 0x%x\n", daemon_msgs);
return;
}
*/
for ( ; !dev->is_open(); ) {
Dmsg1(120, "bstored: open vol=%s\n", dcr->VolumeName);
- if (open_dev(dev, dcr->VolumeName, OPEN_READ_ONLY) < 0) {
+ if (dev->open(dcr->VolumeName, OPEN_READ_ONLY) < 0) {
if (dev->dev_errno == EIO) { /* no tape loaded */
Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
dev->print_name(), dcr->VolumeName, strerror_dev(dev));
dev->print_name(), dcr->VolumeName, strerror_dev(dev));
goto get_out;
}
- Dmsg1(129, "open_dev %s OK\n", dev->print_name());
+ Dmsg1(129, "opened dev %s OK\n", dev->print_name());
}
if (dev->is_dvd()) {
* otherwise mount desired volume obtained from
* dir_find_next_appendable_volume
*/
- bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName));
+ bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
!(dir_find_next_appendable_volume(dcr) &&
- strcmp(dev->VolHdr.VolName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
+ strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
Dmsg0(190, "Wrong tape mounted.\n");
if (dev->num_writers != 0 || dev->reserved_device) {
Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
if (recycle && dev->num_writers != 0) {
Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
" on device %s because it is in use by another job.\n"),
- dev->VolHdr.VolName, dev->print_name());
+ dev->VolHdr.VolumeName, dev->print_name());
goto get_out;
}
if (dev->num_writers == 0) {
/* If no more writers, write an EOF */
if (!dev->num_writers && dev->can_write()) {
weof_dev(dev, 1);
- write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName);
+ write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
}
if (!dev->at_weot()) {
dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
if (VolName && *VolName && *VolName != '*') {
if (!same_label_names(VolName, &label[4])) {
char *p = &label[4];
- char *q = dev->VolHdr.VolName;
+ char *q = dev->VolHdr.VolumeName;
for (int i=0; *p != ' ' && i < 6; i++) {
*q++ = *p++;
}
*q = 0;
- new_volume(dev->VolHdr.VolName, dev);
- Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolName);
- Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolName);
+ new_volume(dev->VolHdr.VolumeName, dev);
+ Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
+ Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolumeName);
return VOL_NAME_ERROR;
}
}
Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
&label[4]);
Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
- dev->VolHdr.VolName);
+ dev->VolHdr.VolumeName);
return VOL_NAME_ERROR; /* Not a Bacula label */
}
break;
pm_strcpy(dev_name, device->hdr.name);
bash_spaces(dev_name);
if (dev->is_labeled()) {
- pm_strcpy(VolumeName, dev->VolHdr.VolName);
+ pm_strcpy(VolumeName, dev->VolHdr.VolumeName);
} else {
pm_strcpy(VolumeName, "*");
}
/*
* Get Volume info for a specific volume from the Director's Database
*
- * Returns: true on success (not Director guarantees that Pool and MediaType
- * are correct and VolStatus==Append or
- * VolStatus==Recycle)
+ * Returns: true on success (Director guarantees that Pool and MediaType
+ * are correct and VolStatus==Append or
+ * VolStatus==Recycle)
* false on failure
*
* Volume information returned in dcr->VolCatInfo
* Handle autoloaders here. If we cannot autoload it, we
* will return 0 so that the sysop will be asked to load it.
*/
- if (writing && dev_cap(dev, CAP_AUTOCHANGER) && slot <= 0) {
+ if (writing && dev->is_autochanger() && slot <= 0) {
if (dir) {
return 0; /* For user, bail out right now */
}
bool ok = false;
int stat;
- if (!dev_cap(dev, CAP_AUTOCHANGER) || !dcr->device->changer_name ||
+ if (!dev->is_autochanger() || !dcr->device->changer_name ||
!dcr->device->changer_command) {
bnet_fsend(dir, _("3993 Device %s not an autochanger device.\n"),
dev->print_name());
# A DVD device
#
#Device {
-# Name = "NEC ND-1300A"
+# Name = "DVD-WRITER"
# Media Type = DVD
# Archive Device = /dev/hdc
# LabelMedia = yes; # lets Bacula label unlabeled media
}
/* For we must now acquire the device for writing */
lock_device(out_dev);
- if (open_dev(out_dev, out_jcr->dcr->VolumeName, OPEN_READ_WRITE) < 0) {
+ if (out_dev->open(out_jcr->dcr->VolumeName, OPEN_READ_WRITE) < 0) {
Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), out_dev->errmsg);
unlock_device(out_dev);
exit(1);
dev->dev_errno = ENOSPC;
return false;
}
- if (!write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName)) {
+ if (!write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName)) {
return false;
}
Dmsg0(100, "WEOF error.\n");
}
if (ok) {
- ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolName);
+ ok = write_ansi_ibm_labels(dcr, ANSI_EOV_LABEL, dev->VolHdr.VolumeName);
}
bstrncpy(dev->VolCatInfo.VolCatStatus, "Full", sizeof(dev->VolCatInfo.VolCatStatus));
dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
if (dev->free_space_errno < 0) { /* Error while getting free space */
char ed1[50], ed2[50];
Dmsg1(10, "Cannot get free space on the device ERR=%s.\n", dev->errmsg);
- Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"),
+ Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s "
+ "(part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"),
dev->VolCatInfo.VolCatName,
dev->file, dev->block_num, dev->print_name(),
edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
if ((dev->free_space_errno > 0 && (dev->part_size + block->binbuf) >= dev->free_space)) {
char ed1[50], ed2[50];
Dmsg0(10, "==== Just enough free space on the device to write the current part...\n");
- Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s (part_size=%s, free_space=%s, free_space_errno=%d).\n"),
+ Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s "
+ "(part_size=%s, free_space=%s, free_space_errno=%d).\n"),
dev->VolCatInfo.VolCatName,
dev->file, dev->block_num, dev->print_name(),
edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
* Assume that we have already read the volume label.
* If on second or subsequent volume, adjust buffer pointer
*/
- if (dev->VolHdr.PrevVolName[0] != 0) { /* second volume */
+ if (dev->VolHdr.PrevVolumeName[0] != 0) { /* second volume */
Pmsg1(0, "\n"
"Warning, this Volume is a continuation of Volume %s\n",
- dev->VolHdr.PrevVolName);
+ dev->VolHdr.PrevVolumeName);
}
if (list_blocks) {
/* Check Media Info */
memset(&mr, 0, sizeof(mr));
- bstrncpy(mr.VolumeName, dev->VolHdr.VolName, sizeof(mr.VolumeName));
+ bstrncpy(mr.VolumeName, dev->VolHdr.VolumeName, sizeof(mr.VolumeName));
mr.PoolId = pr.PoolId;
num_media++;
if (db_get_media_record(bjcr, db, &mr)) {
*/
static void bscan_free_jcr(JCR *jcr)
{
- Dmsg0(200, "Start dird free_jcr\n");
+ Dmsg0(200, "Start bscan free_jcr\n");
if (jcr->file_bsock) {
Dmsg0(200, "Close File bsock\n");
free_dcr(jcr->dcr);
jcr->dcr = NULL;
}
- Dmsg0(200, "End dird free_jcr\n");
+ Dmsg0(200, "End bscan free_jcr\n");
}
/*
lock_device(dev);
if (!dev->is_open()) {
Dmsg1(200, "Opening device %s\n", dcr->VolumeName);
- if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
+ if (dev->open(dcr->VolumeName, OPEN_READ_WRITE) < 0) {
Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
unlock_device(dev);
free_block(block);
return false;
}
}
- Pmsg1(000, "open_dev %s OK\n", dev->print_name());
+ Pmsg1(000, "open_ ev %s OK\n", dev->print_name());
dev->set_append(); /* put volume in append mode */
unlock_device(dev);
free_block(block);
*/
if (VolumeName) {
bstrncpy(VolName, VolumeName, sizeof(VolName));
+ if (strlen(VolumeName) >= MAX_NAME_LENGTH) {
+ Jmsg0(jcr, M_ERROR, 0, _("Volume name or names is too long. Please use a .bsr file.\n"));
+ }
} else {
VolName[0] = 0;
}
/* Functions in dvd.c */
void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
-int mount_dev(DEVICE* dev, int timeout);
-int unmount_dev(DEVICE *dev, int timeout);
void update_free_space_dev(DEVICE* dev);
* (archive_name) with the VolName concatenated.
*/
int
-open_dev(DEVICE *dev, char *VolName, int mode)
+DEVICE::open(char *VolName, int mode)
{
- if (dev->is_open()) {
- if (dev->openmode == mode) {
- return dev->fd;
+ if (is_open()) {
+ if (openmode == mode) {
+ return fd;
} else {
- close(dev->fd); /* close so correct mode will be used */
+ ::close(fd); /* use system close so correct mode will be used on open */
}
}
if (VolName) {
- bstrncpy(dev->VolCatInfo.VolCatName, VolName, sizeof(dev->VolCatInfo.VolCatName));
+ bstrncpy(VolCatInfo.VolCatName, VolName, sizeof(VolCatInfo.VolCatName));
} else {
- dev->VolCatInfo.VolCatName[0] = 0;
+ VolCatInfo.VolCatName[0] = 0;
}
- Dmsg3(29, "open_dev: tape=%d dev_name=%s vol=%s\n", dev->is_tape(),
- dev->dev_name, dev->VolCatInfo.VolCatName);
- dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
- dev->label_type = B_BACULA_LABEL;
- if (dev->is_tape() || dev->is_fifo()) {
- open_tape_device(dev, mode);
+ Dmsg3(29, "open dev: tape=%d dev_name=%s vol=%s\n", is_tape(),
+ dev_name, VolCatInfo.VolCatName);
+ state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
+ label_type = B_BACULA_LABEL;
+ if (is_tape() || is_fifo()) {
+ open_tape_device(this, mode);
} else {
- open_file_device(dev, mode);
+ open_file_device(this, mode);
}
- return dev->fd;
+ return fd;
}
static void open_tape_device(DEVICE *dev, int mode)
dev->file_size = 0;
int timeout;
int ioerrcnt = 10;
- Dmsg0(29, "open_dev: device is tape\n");
+ Dmsg0(29, "open dev: device is tape\n");
if (mode == OPEN_READ_WRITE) {
dev->mode = O_RDWR | O_BINARY;
} else if (mode == OPEN_WRITE_ONLY) {
dev->mode = O_WRONLY | O_BINARY;
} else {
- Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n"));
+ Emsg0(M_ABORT, 0, _("Illegal mode given to open dev.\n"));
}
timeout = dev->max_open_wait;
errno = 0;
stop_thread_timer(dev->tid);
dev->tid = 0;
}
- Dmsg1(29, "open_dev: tape %d opened\n", dev->fd);
+ Dmsg1(29, "open dev: tape %d opened\n", dev->fd);
}
/*
return;
}
- Dmsg3(29, "open_dev: device is %s (mode:%d)\n", dev->is_dvd()?"DVD":"disk",
+ Dmsg3(29, "open dev: device is %s (mode:%d)\n", dev->is_dvd()?"DVD":"disk",
archive_name.c_str(), mode);
dev->openmode = mode;
} else if (mode == OPEN_WRITE_ONLY) {
dev->mode = O_WRONLY | O_BINARY;
} else {
- Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n"));
+ Emsg0(M_ABORT, 0, _("Illegal mode given to open dev.\n"));
}
/* If creating file, give 0640 permissions */
Dmsg2(29, "open(%s, 0x%x, 0640)\n", archive_name.c_str(), dev->mode);
dev->part_size = filestat.st_size;
}
}
- Dmsg5(29, "open_dev: %s fd=%d opened, part=%d/%d, part_size=%u\n",
+ Dmsg5(29, "open dev: %s fd=%d opened, part=%d/%d, part_size=%u\n",
dev->is_dvd()?"DVD":"disk", dev->fd, dev->part, dev->num_parts,
dev->part_size);
if (dev->is_dvd() && (dev->mode != OPEN_READ_ONLY) &&
#define ST_NEXTVOL (1<<13) /* Start writing on next volume */
#define ST_SHORT (1<<14) /* Short block read */
#define ST_MOUNTED (1<<15) /* the device is mounted to the mount point */
-#define ST_OFFLINE (1<<16) /* set offline by operator */
+#define ST_MEDIA (1<<16) /* Media found in mounted device */
+#define ST_OFFLINE (1<<17) /* set offline by operator */
/* dev_blocked states (mutually exclusive) */
enum {
int num_wait;
/* Methods */
+ int is_autochanger() const { return capabilities & CAP_AUTOCHANGER; }
int is_tape() const { return state & ST_TAPE; }
int is_file() const { return state & ST_FILE; }
int is_fifo() const { return state & ST_FIFO; }
int is_offline() const { return state & ST_OFFLINE; }
int is_labeled() const { return state & ST_LABEL; }
int is_mounted() const { return state & ST_MOUNTED; }
+ int have_media() const { return state & ST_MEDIA; }
int is_short_block() const { return state & ST_SHORT; }
int is_busy() const { return state & ST_READ || num_writers || reserved_device; }
int at_eof() const { return state & ST_EOF; }
void set_offline() { state |= ST_OFFLINE; };
void set_opened() { state |= ST_OPENED; };
void set_mounted() { state |= ST_MOUNTED; };
+ void set_media() { state |= ST_MEDIA; };
void set_short_block() { state |= ST_SHORT; };
void set_mounted(int val) { if (val) state |= ST_MOUNTED; \
else state &= ~ST_MOUNTED; };
void clear_eof() { state &= ~ST_EOF; };
void clear_opened() { state &= ~ST_OPENED; };
void clear_mounted() { state &= ~ST_MOUNTED; };
+ void clear_media() { state &= ~ST_MEDIA; };
void clear_short_block() { state &= ~ST_SHORT; };
void block(int why); /* in dev.c */
void unblock(); /* in dev.c */
void close(); /* in dev.c */
+ int open(char *VolName, int mode); /* in dev.c */
void set_blocked(int block) { dev_blocked = block; };
int get_blocked() const { return dev_blocked; };
unlock_device(dev);
bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
- bstrncpy(dev->VolHdr.PrevVolName, PrevVolName, sizeof(dev->VolHdr.PrevVolName));
+ bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
label_blk = new_block(dev);
dcr->block = label_blk;
}
Dmsg0(129, "Opening device.\n");
dev->open_nowait = true;
- if (open_dev(dev, NULL, mode) < 0) {
+ if (dev->open(NULL, mode) < 0) {
Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
dev->open_nowait = false;
unlock_device(dev);
return false;
}
- Dmsg1(129, "open_dev %s OK\n", dev->print_name());
+ Dmsg1(129, "open dev %s OK\n", dev->print_name());
dev->open_nowait = false;
unlock_device(dev);
return true;
} else {
mode = OPEN_READ_WRITE;
}
- if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) {
+ if (dev->open(dcr->VolCatInfo.VolCatName, mode) < 0) {
/* If polling, ignore the error */
if (!dev->poll) {
Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
if (!relabel) {
bnet_fsend(dir, _(
"3920 Cannot label Volume because it is already labeled: \"%s\"\n"),
- dev->VolHdr.VolName);
+ dev->VolHdr.VolumeName);
break;
}
/* Relabel request. If oldname matches, continue */
- if (strcmp(oldname, dev->VolHdr.VolName) != 0) {
+ if (strcmp(oldname, dev->VolHdr.VolumeName) != 0) {
bnet_fsend(dir, _("3921 Wrong volume mounted.\n"));
break;
}
dev->clear_labeled(); /* force read of label */
switch (read_dev_volume_label(dcr)) {
case VOL_OK:
- bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolName);
+ bnet_fsend(dir, _("3001 Mounted Volume: %s\n"), dev->VolHdr.VolumeName);
ok = true;
break;
default:
case BST_UNMOUNTED_WAITING_FOR_SYSOP:
case BST_UNMOUNTED:
/* We freed the device, so reopen it and wake any waiting threads */
- if (open_dev(dev, NULL, OPEN_READ_WRITE) < 0) {
+ if (dev->open(NULL, OPEN_READ_WRITE) < 0) {
bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
strerror_dev(dev));
break;
}
if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
- dev->print_name(), dev->VolHdr.VolName);
+ dev->print_name(), dev->VolHdr.VolumeName);
} else {
bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
"If this is not a blank tape, try unmounting and remounting the Volume.\n"),
if (dev->is_open()) {
if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"),
- dev->print_name(), dev->VolHdr.VolName);
+ dev->print_name(), dev->VolHdr.VolumeName);
} else {
bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
"If this is not a blank tape, try unmounting and remounting the Volume.\n"),
/* Nothing to do */
break;
}
- if (open_dev(dev, NULL, OPEN_READ_WRITE) < 0) {
+ if (dev->open(NULL, OPEN_READ_WRITE) < 0) {
bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"),
strerror_dev(dev));
break;
read_label(dcr);
if (dev->is_labeled()) {
bnet_fsend(dir, _("3001 Device %s is already mounted with Volume \"%s\"\n"),
- dev->print_name(), dev->VolHdr.VolName);
+ dev->print_name(), dev->VolHdr.VolumeName);
} else {
bnet_fsend(dir, _("3905 Device %s open but no Bacula volume is mounted.\n"
"If this is not a blank tape, try unmounting and remounting the Volume.\n"),
switch (read_dev_volume_label(dcr)) {
case VOL_OK:
/* DO NOT add quotes around the Volume name. It is scanned in the DIR */
- bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolName, Slot);
- Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolName);
+ bnet_fsend(dir, _("3001 Volume=%s Slot=%d\n"), dev->VolHdr.VolumeName, Slot);
+ Dmsg1(100, "Volume: %s\n", dev->VolHdr.VolumeName);
break;
default:
bnet_fsend(dir, _("3902 Cannot mount Volume on Storage Device %s because:\n%s"),
/* Ensure that the device is open -- autoload_device() closes it */
for ( ; !dev->is_open(); ) {
- if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
+ if (dev->open(dcr->VolumeName, OPEN_READ_WRITE) < 0) {
bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"),
dev->print_name(), dev->strerror());
return false;
#include "bacula.h"
#include "stored.h"
-int mount_dev(DEVICE *dev, int timeout);
-int unmount_dev(DEVICE *dev, int timeout);
-void update_free_space_dev(DEVICE *dev);
-void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
-
/* Forward referenced functions */
static char *edit_device_codes_dev(DEVICE *dev, char *omsg, const char *imsg);
-static int do_mount_dev(DEVICE* dev, int mount, int dotimeout);
+static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout);
static int dvd_write_part(DEVICE *dev);
/*
* Write the current volume/part filename to archive_name.
*/
-void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name)
+void get_filename(DEVICE *dev, char *VolumeName, POOL_MEM& archive_name)
{
char partnumber[20];
if (archive_name.c_str()[strlen(archive_name.c_str())-1] != '/') {
pm_strcat(archive_name, "/");
}
- pm_strcat(archive_name, VolName);
+ pm_strcat(archive_name, VolumeName);
/* if part != 0, append .# to the filename (where # is the part number) */
if (dev->is_dvd() && dev->part != 0) {
pm_strcat(archive_name, ".");
* If timeout, wait until the mount command returns 0.
* If !timeout, try to mount the device only once.
*/
-int mount_dev(DEVICE* dev, int timeout)
+bool mount_dev(DEVICE* dev, int timeout)
{
if (dev->is_mounted()) {
Dmsg0(100, "mount_dev: Device already mounted\n");
- return 0;
+ return true;
} else if (dev_cap(dev, CAP_REQMOUNT)) {
return do_mount_dev(dev, 1, timeout);
}
- return 0;
+ return true;
}
/* Unmount the device
* If timeout, wait until the unmount command returns 0.
* If !timeout, try to unmount the device only once.
*/
-int unmount_dev(DEVICE *dev, int timeout)
+bool unmount_dev(DEVICE *dev, int timeout)
{
if (dev->is_mounted()) {
return do_mount_dev(dev, 0, timeout);
}
Dmsg0(100, "mount_dev: Device already unmounted\n");
- return 0;
+ return true;
}
/* (Un)mount the device */
-static int do_mount_dev(DEVICE* dev, int mount, int dotimeout)
+static bool do_mount_dev(DEVICE* dev, int mount, int dotimeout)
{
POOL_MEM ocmd(PM_FNAME);
POOLMEM* results;
int status, timeout;
if (mount) {
+ if (dev->is_mounted()) {
+ goto get_out;
+ }
icmd = dev->device->mount_command;
- }
- else {
+ } else {
+ if (!dev->is_mounted()) {
+ goto get_out;
+ }
icmd = dev->device->unmount_command;
}
bmicrosleep(1, 0);
continue;
}
+ Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->print_name(), results);
+ Mmsg(dev->errmsg, "Device %s cannot be mounted. ERR=%s\n",
+ dev->print_name(), results);
free_pool_memory(results);
- Dmsg2(40, "Device %s cannot be mounted. ERR=%s\n", dev->dev_name, results);
- return -1;
+ return false;
}
dev->set_mounted(mount); /* set/clear mounted flag */
+get_out:
free_pool_memory(results);
-
Dmsg1(29, "do_mount_dev: end_state=%d\n", dev->is_mounted());
- return 0;
+ return true;
}
/* Only for devices that require a mount.
* mounted disk is writable. (See also read_dev_volume_label_guess in label.c).
*
* Note that if the right volume is mounted, open_mounted_dev returns
- * the same result as an usual open_dev.
+ * the same result as an usual dev->open().
*/
int open_mounted_dev(DEVICE *dev)
{
if (mount_dev(dev, 1) < 0) {
/* If the device cannot be mounted, check if it is writable */
- if (dev->free_space_errno >= 0) {
+ if (dev->have_media()) {
Dmsg1(100, "open_mounted_dev: device cannot be mounted, but it seems to be writable, returning 0. dev=%s\n", dev->dev_name);
return 0;
} else {
if (!icmd) {
dev->free_space = 0;
dev->free_space_errno = 0;
+ dev->clear_media();
Dmsg2(29, "update_free_space_dev: free_space=%d, free_space_errno=%d (!icmd)\n", dev->free_space, dev->free_space_errno);
return;
}
if (free >= 0) {
dev->free_space = free;
dev->free_space_errno = 1;
+ dev->set_media();
Mmsg0(dev->errmsg, "");
break;
}
}
free_pool_memory(results);
- Dmsg2(29, "update_free_space_dev: free_space=%s, free_space_errno=%d\n",
- edit_uint64(dev->free_space, ed1), dev->free_space_errno);
+ Dmsg3(29, "update_free_space_dev: free_space=%s, free_space_errno=%d have_media=%d\n",
+ edit_uint64(dev->free_space, ed1), dev->free_space_errno, dev->have_media());
return;
}
}
}
- Dmsg2(50, "Call open_dev(dev, vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
+ Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
dev->openmode);
- if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
+ if (dev->open(dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
return -1;
}
return dev->fd;
dev->part_start = 0;
dev->part = 0;
- Dmsg2(50, "Call open_dev(dev, vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
+ Dmsg2(50, "Call dev->open(vol=%s, mode=%d", dev->VolCatInfo.VolCatName,
dev->openmode);
- if (open_dev(dev, dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
- Dmsg0(50, "open_dev() failed\n");
+ if (dev->open(dev->VolCatInfo.VolCatName, dev->openmode) < 0) {
+ Dmsg0(50, "open dev() failed\n");
return -1;
}
Dmsg1(50, "Leave open_first_part state=%s\n", dev->is_open()?"open":"not open");
bool want_ansi_label;
Dmsg3(100, "Enter read_volume_label device=%s vol=%s dev_Vol=%s\n",
- dev->name(), VolName, dev->VolHdr.VolName);
+ dev->name(), VolName, dev->VolHdr.VolumeName);
if (!dev->is_open()) {
Emsg0(M_ABORT, 0, _("BAD call to read_dev_volume_label\n"));
}
if (dev->is_labeled()) { /* did we already read label? */
/* Compare Volume Names allow special wild card */
- if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
+ if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolumeName, VolName) != 0) {
Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
- dev->print_name(), VolName, dev->VolHdr.VolName);
+ dev->print_name(), VolName, dev->VolHdr.VolumeName);
/*
* Cancel Job if too many label errors
* => we are in a loop
}
if (stat == VOL_NAME_ERROR || stat == VOL_LABEL_ERROR) {
Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
- dev->print_name(), VolName, dev->VolHdr.VolName);
+ dev->print_name(), VolName, dev->VolHdr.VolumeName);
if (!dev->poll && jcr->label_errors++ > 100) {
Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
}
}
dev->set_labeled(); /* set has Bacula label */
- new_volume(dev->VolHdr.VolName, dev);
+ new_volume(dev->VolHdr.VolumeName, dev);
/* Compare Volume Names */
- Dmsg2(30, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolName);
- if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
+ Dmsg2(30, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolumeName);
+ if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolumeName, VolName) != 0) {
Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
- dev->print_name(), VolName, dev->VolHdr.VolName);
+ dev->print_name(), VolName, dev->VolHdr.VolumeName);
Dmsg1(30, "%s", jcr->errmsg);
/*
* Cancel Job if too many label errors
}
return VOL_NAME_ERROR;
}
- Dmsg1(30, "Copy vol_name=%s\n", dev->VolHdr.VolName);
+ Dmsg1(30, "Copy vol_name=%s\n", dev->VolHdr.VolumeName);
if (debug_level >= 10) {
dump_volume_label(dev);
DEVICE *dev = dcr->dev;
JCR *jcr = dcr->jcr;
Dmsg3(100, "Enter read_dvd_volume_label device=%s vol=%s dev_Vol=%s\n",
- dev->print_name(), dcr->VolumeName, dev->VolHdr.VolName);
+ dev->print_name(), dcr->VolumeName, dev->VolHdr.VolumeName);
if (!dev->is_dvd()) {
Jmsg1(jcr, M_ABORT, 0, _("Device %s is not a DVD.\n"), dev->print_name());
if (weof_dev(dev, 1) == 0) {
dev->set_labeled();
- write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName);
+ write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
}
if (debug_level >= 20) {
rewind_dev(dev);
return false;
}
- } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, dev->VolHdr.VolName)) {
+ } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, dev->VolHdr.VolumeName)) {
return false;
}
ser_float64(dev->VolHdr.write_date); /* 0 if VerNum >= 11 */
ser_float64(dev->VolHdr.write_time); /* 0 if VerNum >= 11 */
- ser_string(dev->VolHdr.VolName);
- ser_string(dev->VolHdr.PrevVolName);
+ ser_string(dev->VolHdr.VolumeName);
+ ser_string(dev->VolHdr.PrevVolumeName);
ser_string(dev->VolHdr.PoolName);
ser_string(dev->VolHdr.PoolType);
ser_string(dev->VolHdr.MediaType);
bstrncpy(dev->VolHdr.Id, BaculaId, sizeof(dev->VolHdr.Id));
dev->VolHdr.VerNum = BaculaTapeVersion;
dev->VolHdr.LabelType = PRE_LABEL; /* Mark tape as unused */
- bstrncpy(dev->VolHdr.VolName, VolName, sizeof(dev->VolHdr.VolName));
+ bstrncpy(dev->VolHdr.VolumeName, VolName, sizeof(dev->VolHdr.VolumeName));
bstrncpy(dev->VolHdr.PoolName, PoolName, sizeof(dev->VolHdr.PoolName));
bstrncpy(dev->VolHdr.MediaType, device->media_type, sizeof(dev->VolHdr.MediaType));
unser_float64(dev->VolHdr.write_date); /* Unused with VerNum >= 11 */
unser_float64(dev->VolHdr.write_time); /* Unused with VerNum >= 11 */
- unser_string(dev->VolHdr.VolName);
- unser_string(dev->VolHdr.PrevVolName);
+ unser_string(dev->VolHdr.VolumeName);
+ unser_string(dev->VolHdr.PrevVolumeName);
unser_string(dev->VolHdr.PoolName);
unser_string(dev->VolHdr.PoolType);
unser_string(dev->VolHdr.MediaType);
"HostName : %s\n"
"",
dev->VolHdr.Id, dev->VolHdr.VerNum,
- dev->VolHdr.VolName, dev->VolHdr.PrevVolName,
+ dev->VolHdr.VolumeName, dev->VolHdr.PrevVolumeName,
File, LabelType, dev->VolHdr.LabelSize,
dev->VolHdr.PoolName, dev->VolHdr.MediaType,
dev->VolHdr.PoolType, dev->VolHdr.HostName);
* so can do fast rejection.
*
* returns: 1 if block may contain valid records
- * 0 if block may be skipped (i.e. it contains no records of
- * that can match the bsr).
+ * 0 if block may be skipped (i.e. it contains no records of
+ * that can match the bsr).
*
*/
int match_bsr_block(BSR *bsr, DEV_BLOCK *block)
{
if (!bsr || !bsr->use_fast_rejection || (block->BlockVer < 2)) {
- return 1; /* cannot fast reject */
+ return 1; /* cannot fast reject */
}
for ( ; bsr; bsr=bsr->next) {
if (!match_block_sesstime(bsr, bsr->sesstime, block)) {
- continue;
+ continue;
}
if (!match_block_sessid(bsr, bsr->sessid, block)) {
- continue;
+ continue;
}
return 1;
}
static int match_block_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_BLOCK *block)
{
if (!sesstime) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (sesstime->sesstime == block->VolSessionTime) {
return 1;
static int match_block_sessid(BSR *bsr, BSR_SESSID *sessid, DEV_BLOCK *block)
{
if (!sessid) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (sessid->sessid <= block->VolSessionId && sessid->sessid2 >= block->VolSessionId) {
return 1;
/*********************************************************************
*
- * Match Bootstrap records
- * returns 1 on match
- * returns 0 no match and reposition is set if we should
- * reposition the tape
- * returns -1 no additional matches possible
+ * Match Bootstrap records
+ * returns 1 on match
+ * returns 0 no match and reposition is set if we should
+ * reposition the tape
+ * returns -1 no additional matches possible
*/
int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec)
{
/*
* The bsr->reposition flag is set any time a bsr is done.
- * In this case, we can probably reposition the
- * tape to the next available bsr position.
+ * In this case, we can probably reposition the
+ * tape to the next available bsr position.
*/
if (bsr) {
bsr->reposition = false;
* found or if we cannot use positioning
*/
if (stat != 0 || !bsr->use_positioning) {
- bsr->reposition = false;
+ bsr->reposition = false;
}
} else {
- stat = 1; /* no bsr => match all */
+ stat = 1; /* no bsr => match all */
}
return stat;
}
root_bsr->mount_next_volume = false;
for (bsr=root_bsr; bsr; bsr=bsr->next) {
if (bsr->done || !match_volume(bsr, bsr->volume, &dev->VolHdr, 1)) {
- continue;
+ continue;
}
if (found_bsr == NULL) {
- found_bsr = bsr;
+ found_bsr = bsr;
} else {
- found_bsr = find_smallest_volfile(found_bsr, bsr);
+ found_bsr = find_smallest_volfile(found_bsr, bsr);
}
}
/*
found_bsr_sfile = vf->sfile;
while ( (vf=vf->next) ) {
if (vf->sfile < found_bsr_sfile) {
- found_bsr_sfile = vf->sfile;
+ found_bsr_sfile = vf->sfile;
}
}
vf = bsr->volfile;
bsr_sfile = vf->sfile;
while ( (vf=vf->next) ) {
if (vf->sfile < bsr_sfile) {
- bsr_sfile = vf->sfile;
+ bsr_sfile = vf->sfile;
}
}
if (found_bsr_sfile > bsr_sfile) {
vb = found_bsr->volblock;
found_bsr_sblock = vb->sblock;
while ( (vb=vb->next) ) {
- if (vb->sblock < found_bsr_sblock) {
- found_bsr_sblock = vb->sblock;
- }
+ if (vb->sblock < found_bsr_sblock) {
+ found_bsr_sblock = vb->sblock;
+ }
}
vb = bsr->volblock;
bsr_sblock = vb->sblock;
while ( (vb=vb->next) ) {
- if (vb->sblock < bsr_sblock) {
- bsr_sblock = vb->sblock;
- }
+ if (vb->sblock < bsr_sblock) {
+ bsr_sblock = vb->sblock;
+ }
}
if (found_bsr_sblock > bsr_sblock) {
- return_bsr = bsr;
+ return_bsr = bsr;
}
}
* for consistency with the other match calls.
*
* Returns: true if we should reposition
- * : false otherwise.
+ * : false otherwise.
*/
bool match_set_eof(BSR *bsr, DEV_RECORD *rec)
{
rbsr->done = true;
rbsr->root->reposition = true;
Dmsg2(100, "match_set_eof reposition count=%d found=%d\n",
- rbsr->count, rbsr->found);
+ rbsr->count, rbsr->found);
return true;
}
return false;
* returns -1 no additional matches possible
*/
static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
- SESSION_LABEL *sessrec, bool done)
+ SESSION_LABEL *sessrec, bool done)
{
if (bsr->done) {
goto no_match;
}
if (!match_volfile(bsr, bsr->volfile, rec, 1)) {
Dmsg2(100, "Fail on file. bsr=%d rec=%d\n", bsr->volfile->efile,
- rec->File);
+ rec->File);
goto no_match;
}
if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) {
Dmsg2(100, "Fail on sesstime. bsr=%d rec=%d\n",
- bsr->sesstime->sesstime, rec->VolSessionTime);
+ bsr->sesstime->sesstime, rec->VolSessionTime);
goto no_match;
}
/* NOTE!! This test MUST come after the sesstime test */
if (!match_sessid(bsr, bsr->sessid, rec)) {
Dmsg2(100, "Fail on sessid. bsr=%d rec=%d\n",
- bsr->sessid->sessid, rec->VolSessionId);
+ bsr->sessid->sessid, rec->VolSessionId);
goto no_match;
}
/* NOTE!! This test MUST come after sesstime and sessid tests */
if (!match_findex(bsr, bsr->FileIndex, rec, 1)) {
Dmsg2(100, "Fail on findex. bsr=%d rec=%d\n",
- bsr->FileIndex->findex2, rec->FileIndex);
+ bsr->FileIndex->findex2, rec->FileIndex);
goto no_match;
}
/*
* If a count was specified and we have a FileIndex, assume
- * it is a Bacula created bsr (or the equivalent). We
- * then save the bsr where the match occurred so that
- * after processing the record or records, we can update
- * the found count. I.e. rec->bsr points to the bsr that
- * satisfied the match.
+ * it is a Bacula created bsr (or the equivalent). We
+ * then save the bsr where the match occurred so that
+ * after processing the record or records, we can update
+ * the found count. I.e. rec->bsr points to the bsr that
+ * satisfied the match.
*/
if (bsr->count && bsr->FileIndex) {
rec->bsr = bsr;
- return 1; /* this is a complete match */
+ return 1; /* this is a complete match */
}
/*
* The selections below are not used by Bacula's
* restore command, and don't work because of
- * the rec->bsr = bsr optimization above.
+ * the rec->bsr = bsr optimization above.
*/
if (!match_jobid(bsr, bsr->JobId, sessrec, 1)) {
goto no_match;
static int match_volume(BSR *bsr, BSR_VOLUME *volume, VOLUME_LABEL *volrec, bool done)
{
if (!volume) {
- return 0; /* Volume must match */
+ return 0; /* Volume must match */
}
- if (strcmp(volume->VolumeName, volrec->VolName) == 0) {
+ if (strcmp(volume->VolumeName, volrec->VolumeName) == 0) {
return 1;
}
if (volume->next) {
static int match_client(BSR *bsr, BSR_CLIENT *client, SESSION_LABEL *sessrec, bool done)
{
if (!client) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (fnmatch(client->ClientName, sessrec->ClientName, 0) == 0) {
return 1;
static int match_job(BSR *bsr, BSR_JOB *job, SESSION_LABEL *sessrec, bool done)
{
if (!job) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (fnmatch(job->Job, sessrec->Job, 0) == 0) {
return 1;
static int match_job_type(BSR *bsr, BSR_JOBTYPE *job_type, SESSION_LABEL *sessrec, bool done)
{
if (!job_type) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (job_type->JobType == sessrec->JobType) {
return 1;
static int match_job_level(BSR *bsr, BSR_JOBLEVEL *job_level, SESSION_LABEL *sessrec, bool done)
{
if (!job_level) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (job_level->JobLevel == sessrec->JobLevel) {
return 1;
static int match_jobid(BSR *bsr, BSR_JOBID *jobid, SESSION_LABEL *sessrec, bool done)
{
if (!jobid) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (jobid->JobId <= sessrec->JobId && jobid->JobId2 >= sessrec->JobId) {
return 1;
static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, bool done)
{
if (!volfile) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
/* For the moment, these tests work only with tapes. */
if (!(rec->state & REC_ISTAPE)) {
- return 1; /* All File records OK for this match */
+ return 1; /* All File records OK for this match */
}
// Dmsg3(100, "match_volfile: sfile=%d efile=%d recfile=%d\n",
-// volfile->sfile, volfile->efile, rec->File);
+// volfile->sfile, volfile->efile, rec->File);
if (volfile->sfile <= rec->File && volfile->efile >= rec->File) {
return 1;
}
/* Once we get past last efile, we are done */
if (rec->File > volfile->efile) {
- volfile->done = true; /* set local done */
+ volfile->done = true; /* set local done */
}
if (volfile->next) {
return match_volfile(bsr, volfile->next, rec, volfile->done && done);
bsr->done = true;
bsr->root->reposition = true;
Dmsg2(100, "bsr done from volfile rec=%d volefile=%d\n",
- rec->File, volfile->efile);
+ rec->File, volfile->efile);
}
return 0;
}
static int match_stream(BSR *bsr, BSR_STREAM *stream, DEV_RECORD *rec, bool done)
{
if (!stream) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (stream->stream == rec->Stream) {
return 1;
static int match_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_RECORD *rec, bool done)
{
if (!sesstime) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (sesstime->sesstime == rec->VolSessionTime) {
return 1;
static int match_sessid(BSR *bsr, BSR_SESSID *sessid, DEV_RECORD *rec)
{
if (!sessid) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (sessid->sessid <= rec->VolSessionId && sessid->sessid2 >= rec->VolSessionId) {
return 1;
* ***FIXME*** optimizations
* We could optimize a lot here by removing the recursion, and
* stopping the search earlier -- say when rec->FileIndex > findex->findex2
- * and findex->next == NULL. Also, the current entry tests could be skipped
+ * and findex->next == NULL. Also, the current entry tests could be skipped
* if findex->done is set.
*/
static int match_findex(BSR *bsr, BSR_FINDEX *findex, DEV_RECORD *rec, bool done)
{
if (!findex) {
- return 1; /* no specification matches all */
+ return 1; /* no specification matches all */
}
if (findex->findex <= rec->FileIndex && findex->findex2 >= rec->FileIndex) {
return 1;
Dmsg1(100, "Vol NAME Error Name=%s\n", dcr->VolumeName);
/* If polling and got a previous bad name, ignore it */
- if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolName) == 0) {
+ if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
ask = true;
Dmsg1(200, "Vol Name error supress due to poll. Name=%s\n",
dcr->VolumeName);
if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
/* Restore desired volume name, note device info out of sync */
/* This gets the info regardless of the Pool */
- bstrncpy(dcr->VolumeName, dev->VolHdr.VolName, sizeof(dcr->VolumeName));
+ bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
if (autochanger && dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
mark_volume_not_inchanger(dcr);
}
memcpy(&dev->VolCatInfo, &devVolCatInfo, sizeof(dev->VolCatInfo));
- bstrncpy(dev->BadVolName, dev->VolHdr.VolName, sizeof(dev->BadVolName));
+ bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n"
" Current Volume \"%s\" not acceptable because:\n"
" %s"),
- VolCatInfo.VolCatName, dev->VolHdr.VolName,
+ VolCatInfo.VolCatName, dev->VolHdr.VolumeName,
jcr->dir_bsock->msg);
ask = true;
goto mount_next_vol;
/* From dev.c */
DEVICE *init_dev(JCR *jcr, DEVRES *device);
-int open_dev(DEVICE *dev, char *VolName, int mode);
off_t lseek_dev(DEVICE *dev, off_t offset, int whence);
int open_first_part(DEVICE *dev);
int open_next_part(DEVICE *dev);
/* From dvd.c */
bool dvd_close_job(DCR *dcr);
-
+bool mount_dev(DEVICE* dev, int timeout);
+bool unmount_dev(DEVICE* dev, int timeout);
+void update_free_space_dev(DEVICE *dev);
+void get_filename(DEVICE *dev, char *VolName, POOL_MEM& archive_name);
/* From device.c */
bool open_device(DCR *dcr);
float64_t write_date; /* Date this label written */
float64_t write_time; /* Time this label written */
- char VolName[MAX_NAME_LENGTH]; /* Volume name */
- char PrevVolName[MAX_NAME_LENGTH]; /* Previous Volume Name */
+ char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
+ char PrevVolumeName[MAX_NAME_LENGTH]; /* Previous Volume Name */
char PoolName[MAX_NAME_LENGTH]; /* Pool name */
char PoolType[MAX_NAME_LENGTH]; /* Pool type */
char MediaType[MAX_NAME_LENGTH]; /* Type of this media */
char *device_name;
DIRSTORE *store;
DEVRES *device;
+ bool PreferMountedVols;
};
static dlist *vol_list = NULL;
static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
/* Forward referenced functions */
-static int can_reserve_drive(DCR *dcr);
+static int can_reserve_drive(DCR *dcr, bool PerferMountedVols);
static int search_res_for_device(RCTX &rctx);
static int reserve_device(RCTX &rctx);
static bool reserve_device_for_read(DCR *dcr);
-static bool reserve_device_for_append(DCR *dcr);
+static bool reserve_device_for_append(DCR *dcr, bool PreferMountedVols);
static bool use_storage_cmd(JCR *jcr);
bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx);
bool use_cmd(JCR *jcr)
{
/*
- * Wait for the device, media, and pool information
+ * Get the device, media, and pool information
*/
if (!use_storage_cmd(jcr)) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
{
VOLRES vol, *fvol;
- if (dev->VolHdr.VolName[0] == 0) {
+ if (dev->VolHdr.VolumeName[0] == 0) {
return false;
}
- vol.vol_name = bstrdup(dev->VolHdr.VolName);
+ vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
P(vol_list_lock);
fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
if (fvol) {
}
V(vol_list_lock);
free(vol.vol_name);
- dev->VolHdr.VolName[0] = 0;
+ dev->VolHdr.VolumeName[0] = 0;
return fvol != NULL;
}
* Wiffle through them and find one that can do the backup.
*/
if (ok) {
+ /*
+ * Make up to two passes. The first with PreferMountedVols possibly
+ * set to true. In that case, we look only for an available
+ * drive with something mounted. If that fails, then we
+ * do a second pass with PerferMountedVols set false.
+ */
+ rctx.PreferMountedVols = jcr->PreferMountedVols;
ok = find_suitable_device_for_job(jcr, rctx);
if (ok) {
goto done;
}
+ if (rctx.PreferMountedVols) {
+ rctx.PreferMountedVols = false;
+ ok = find_suitable_device_for_job(jcr, rctx);
+ if (ok) {
+ goto done;
+ }
+ }
if (verbose) {
unbash_spaces(dir->msg);
pm_strcpy(jcr->errmsg, dir->msg);
bstrncpy(dcr->media_type, rctx.store->media_type, name_len);
bstrncpy(dcr->dev_name, rctx.device_name, name_len);
if (rctx.store->append == SD_APPEND) {
- ok = reserve_device_for_append(dcr);
+ ok = reserve_device_for_append(dcr, rctx.PreferMountedVols);
Dmsg3(200, "dev_name=%s mediatype=%s ok=%d\n", dcr->dev_name, dcr->media_type, ok);
} else {
ok = reserve_device_for_read(dcr);
* the first tor reserve the device, we put the pool
* name and pool type in the device record.
*/
-static bool reserve_device_for_append(DCR *dcr)
+static bool reserve_device_for_append(DCR *dcr, bool PreferMountedVols)
{
JCR *jcr = dcr->jcr;
DEVICE *dev = dcr->dev;
if (dev->can_read()) {
Mmsg1(jcr->errmsg, _("Device %s is busy reading.\n"), dev->print_name());
+ Dmsg1(100, "%s", jcr->errmsg);
goto bail_out;
}
if (device_is_unmounted(dev)) {
Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"), dev->print_name());
+ Dmsg1(100, "%s", jcr->errmsg);
goto bail_out;
}
Dmsg1(190, "reserve_append device is %s\n", dev->is_tape()?"tape":"disk");
- if (can_reserve_drive(dcr) != 1) {
+ if (can_reserve_drive(dcr, PreferMountedVols) != 1) {
Mmsg1(jcr->errmsg, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
+ Dmsg1(100, "%s", jcr->errmsg);
goto bail_out;
}
* 0 if we should wait
* -1 on error
*/
-static int can_reserve_drive(DCR *dcr)
+static int can_reserve_drive(DCR *dcr, bool PreferMountedVols)
{
DEVICE *dev = dcr->dev;
JCR *jcr = dcr->jcr;
+
+ if (PreferMountedVols && !dev->VolHdr.VolumeName[0] &&
+ dev->is_tape() && !dev->is_autochanger()) {
+ return 0; /* No volume mounted */
+ }
+
/*
- * First handle the case that the drive is not yet in append mode
+ * Handle the case that the drive is not yet in append mode
*/
if (!dev->can_append() && dev->num_writers == 0) {
/* Now check if there are any reservations on the drive */
bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
return 1;
}
-
/*
- * Now check if the device is in append mode with writers (i.e.
+ * Check if the device is in append mode with writers (i.e.
* available if pool is the same).
*/
if (dev->can_append() || dev->num_writers > 0) {
if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
strcmp(dev->pool_type, dcr->pool_type) == 0) {
/* OK, compatible device */
+ return 1;
} else {
/* Drive not suitable for us */
Jmsg(jcr, M_WARNING, 0, _("Device %s is busy writing on another Volume.\n"), dev->print_name());
Jmsg0(jcr, M_FATAL, 0, _("Logic error!!!! Should not get here.\n"));
return -1; /* error, should not get here */
}
- return 1; /* reserve drive */
+
+ return 0;
}
if (dev && dev->is_open()) {
if (dev->is_labeled()) {
bnet_fsend(user, _("Device %s is mounted with Volume \"%s\"\n"),
- dev->print_name(), dev->VolHdr.VolName);
+ dev->print_name(), dev->VolHdr.VolumeName);
} else {
bnet_fsend(user, _("Device %s open but no Bacula volume is mounted.\n"),
dev->print_name());
P(device_release_mutex);
if (first) {
- Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting to obtain a device.\n"), jcr->Job);
+ Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting to reserve a device.\n"), jcr->Job);
}
/*
if (!double_jcr_wait_time(jcr)) {
break; /* give up */
}
- Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting to obtain a device.\n"), jcr->Job);
+ Jmsg(jcr, M_MOUNT, 0, _("Job %s waiting to reserve a device.\n"), jcr->Job);
}
add_wait = jcr->wait_sec - (now - start);
/* */
#undef VERSION
-#define VERSION "1.37.23"
-#define BDATE "14 June 2005"
-#define LSMDATE "14Jun05"
+#define VERSION "1.37.24"
+#define BDATE "16 June 2005"
+#define LSMDATE "16Jun05"
/* Debug flags */
#undef DEBUG
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// http://66.102.9.104/search?q=cache:Djc1mPF3hRoJ:cvs.sourceforge.net/viewcvs.py/audacity/audacity-src/src/AudioIO.cpp%3Frev%3D1.102+macos+x+wxthread&hl=fr
#ifndef WIN32
add_msg_dest(msgs, MD_STDOUT, i, NULL, NULL);
#endif
- add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
+// add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
add_msg_dest(msgs, MD_CONSOLE, i, NULL, NULL);
}
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// ============================================================================
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxbconfigfileeditor.h"
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxbconfigpanel.h"
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxbhistorytextctrl.h"
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxblistctrl.h"
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxbmainframe.h" // class's header file
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
+
/* Note concerning "done" output (modifiable marked with +)
Run Restore job
+JobName: RestoreFiles
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxbtableparser.h" // class's header file
* Version $Id$
*/
/*
- Copyright (C) 2004 Kern Sibbald and John Walker
+ Copyright (C) 2004-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxbtreectrl.h"
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
+ version 2 as ammended 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
- GNU General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ the file LICENSE for additional 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "wxbutils.h"