a DB upgrade.
Major Changes:
+- The Python interface has been updated to be object oriented.
- This version has a new DIR <--> SD protocol. Both must be
upgraded at the same time.
- This version has a new database format that is not compatible
import bacula
- The script is called with one argument, typically called j. This
- argument *must* be passed unchanged to each bacula function. The
+ The script is called with one argument, typically called jcr. This
+ argument *must* be used to access each bacula function. The
format of the call is slightly different for reading Bacula
variable and for writing bacula variables. See below.
Bacula variables can be read with:
- bacula.get(j, "Variable-name")
+ jcr.get("Variable-name")
- where j is the argument passed to the function, and Variable-name
+ where jcr is the argument passed to the function, and Variable-name
is on of the following:
JobId, Client, Pool, Storage, Catalog, MediaType, NumVols, DirName,
Bacula varibles can be set using Python keyword arguments:
- bacula.set(jcr=j, VolumeName="xyz")
+ jcr.set(VolumeName="xyz")
The two currently implemented writable "variables" are:
It is possible to submit a Bacula run command with the following:
- bacula.run(j, "run kernsave client=Matou storage=File")
+ jcr.run("run kernsave client=Matou storage=File")
this function returns the JobId of the job that was started. If
there is an error, the return value is zero.
== File EndJob.py ===
import bacula
-def EndJob(j):
- jobid = bacula.get(j, "JobId")
- client = bacula.get(j, "Client")
- bacula.set(jcr=j, JobReport="EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
+def EndJob(jcr):
+ jobid = jcr.get("JobId")
+ client = jcr.get("Client")
+ jcr.set(JobReport="EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
if (jobid < 5) :
- startid = bacula.run(j, "run kernsave")
+ startid = jcr.run("run kernsave")
print "Python started jobid=", startid
return 1
== File NewVolume.py ===
import bacula
-def NewVolume(j):
- jobid = bacula.get(j, "JobId")
+def NewVolume(jcr):
+ jobid = jcr.get("JobId")
print "JobId=", jobid
- client = bacula.get(j, "Client")
+ client = jcr.get("Client")
print "Client=" + client
- numvol = bacula.get(j, "NumVols");
+ numvol = jcr.get("NumVols");
print "NumVols=", numvol
- bacula.set(jcr=j, JobReport="New Volume set for Job.\n")
- bacula.set(jcr=j, VolumeName="TestA-001")
+ jcr.set(JobReport="New Volume set for Job.\n")
+ jcr.set(VolumeName="TestA-001")
return 1
====
import bacula
-def EndJob(j):
- jobid = bacula.get(j, "JobId")
- client = bacula.get(j, "Client")
- bacula.set(jcr=j, JobReport="Python EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
+def EndJob(jcr):
+ jobid = jcr.get("JobId")
+ client = jcr.get("Client")
+ jcr.set(JobReport="Python EndJob output: JobId=%d Client=%s.\n" % (jobid, client))
if (jobid < 2) :
- startid = bacula.run(j, "run kernsave")
+ startid = bacula.run("run kernsave")
print "Python started new Job: jobid=", startid
return 1
import bacula
-def NewVolume(j):
- jobid = bacula.get(j, "JobId")
+def NewVolume(jcr):
+ jobid = jcr.get("JobId")
print "JobId=", jobid
- client = bacula.get(j, "Client")
+ client = jcr.get("Client")
print "Client=" + client
- numvol = bacula.get(j, "NumVols");
+ numvol = jcr.get("NumVols");
print "NumVols=", numvol
- bacula.set(jcr=j, JobReport="Python New Volume set for Job.\n")
- bacula.set(jcr=j, VolumeName="TestA-001")
+ jcr.set(JobReport="Python New Volume set for Job.\n")
+ jcr.set(VolumeName="TestA-001")
return 1
import bacula
-def StartJob(j):
- jobid = bacula.get(j, "JobId")
- client = bacula.get(j, "Client")
- numvols = bacula.get(j, "NumVols")
- bacula.set(jcr=j, JobReport="Python StartJob: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols))
+def StartJob(jcr):
+ jobid = jcr.get("JobId")
+ client = jcr.get("Client")
+ numvols = jcr.get("NumVols")
+ jcr.set(JobReport="Python StartJob: JobId=%d Client=%s NumVols=%d\n" % (jobid,client,numvols))
return 1
- Add history file to console.
Maybe in 1.37:
+- Ensure that you cannot exclude a directory or a file explicitly
+ Included with File.
+- Each file on tape creates a JobMedia record. Peter has 4 million
+ files spread over 10000 tape files and four tapes. A restore takes
+ 16 hours to build the restore list.
- By the way: on page http://www.bacula.org/?page=tapedrives , at the
bottom, the link to "Tape Testing Chapter" is broken. It goes to
/html-manual/... while the others point to /rel-manual/...
PRIMARY KEY (MediaId)
);
+CREATE TABLE Status (
+ JobStatus CHAR(1) BINARY NOT NULL,
+ JobStatusLong BLOB,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
CREATE TABLE Version (
VersionId INTEGER UNSIGNED NOT NULL
);
versionid integer not null
);
+CREATE TABLE Status (
+ JobStatus CHAR(1) NOT NULL,
+ JobStatusLong TEXT,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
+
INSERT INTO Version (VersionId) VALUES (9);
-- Make sure we have appropriate permissions
PRIMARY KEY (MediaId)
);
+
+CREATE TABLE Status (
+ JobStatus CHAR(1) BINARY NOT NULL,
+ JobStatusLong BLOB,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
+
-- Initialize Version
INSERT INTO Version (VersionId) VALUES (9);
+
PRAGMA default_synchronous = OFF;
PRAGMA default_cache_size = 10000;
PRIMARY KEY (MediaId)
);
+
+CREATE TABLE Status (
+ JobStatus CHAR(1) BINARY NOT NULL,
+ JobStatusLong BLOB,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
+
-- Initialize Version
INSERT INTO Version (VersionId) VALUES (9);
+
PRAGMA default_synchronous = OFF;
PRAGMA default_cache_size = 10000;
PRIMARY KEY(DeviceId)
);
+CREATE TABLE Status (
+ JobStatus CHAR(1) BINARY NOT NULL,
+ JobStatusLong BLOB,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
+
DELETE FROM Version;
INSERT INTO Version (VersionId) VALUES (9);
PRIMARY KEY(StorageId)
);
+CREATE TABLE Status (
+ JobStatus CHAR(1) NOT NULL,
+ JobStatusLong TEXT,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
+
DELETE FROM version;
INSERT INTO version (versionId) VALUES (9);
);
+CREATE TABLE Status (
+ JobStatus CHAR(1) NOT NULL,
+ JobStatusLong BLOB,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
+
DELETE FROM Version;
INSERT INTO Version (VersionId) VALUES (9);
);
+CREATE TABLE Status (
+ JobStatus CHAR(1) NOT NULL,
+ JobStatusLong BLOB,
+ PRIMARY KEY (JobStatus)
+ );
+
+INSERT INTO Status (JobStatus,JobStatusLong) VALUES
+ ('C', 'Created, not yet running'),
+ ('R', 'Running'),
+ ('B', 'Blocked'),
+ ('T', 'Completed successfully'),
+ ('E', 'Terminated with errors'),
+ ('e', 'Non-fatal error'),
+ ('f', 'Fatal error'),
+ ('D', 'Verify found differences'),
+ ('A', 'Canceled by user'),
+ ('F', 'Waiting for Client'),
+ ('S', 'Waiting for Storage daemon'),
+ ('m', 'Waiting for new media'),
+ ('M', 'Waiting for media mount'),
+ ('s', 'Waiting for storage resource'),
+ ('j', 'Waiting for job resource'),
+ ('c', 'Waiting for client resource'),
+ ('d', 'Waiting on maximum jobs'),
+ ('t', 'Waiting on start time'),
+ ('p', 'Waiting on higher priority jobs');
+
+
DELETE FROM Version;
INSERT INTO Version (VersionId) VALUES (9);
void term_job_server()
{
- jobq_destroy(&job_queue); /* ignore any errors */
+ jobq_destroy(&job_queue); /* ignore any errors */
}
/*
* Run a job -- typically called by the scheduler, but may also
- * be called by the UA (Console program).
+ * be called by the UA (Console program).
*
* Returns: 0 on failure
- * JobId on success
+ * JobId on success
*
*/
JobId_t run_job(JCR *jcr)
*/
Dmsg0(50, "Open database\n");
jcr->db=db_init_database(jcr, jcr->catalog->db_name, jcr->catalog->db_user,
- jcr->catalog->db_password, jcr->catalog->db_address,
- jcr->catalog->db_port, jcr->catalog->db_socket,
- jcr->catalog->mult_db_connections);
+ jcr->catalog->db_password, jcr->catalog->db_address,
+ jcr->catalog->db_port, jcr->catalog->db_socket,
+ jcr->catalog->mult_db_connections);
if (!jcr->db || !db_open_database(jcr, jcr->db)) {
Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
- jcr->catalog->db_name);
+ jcr->catalog->db_name);
if (jcr->db) {
Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
}
switch (jcr->JobType) {
case JT_BACKUP:
if (!do_backup_init(jcr)) {
- backup_cleanup(jcr, JS_ErrorTerminated);
+ backup_cleanup(jcr, JS_ErrorTerminated);
}
break;
case JT_VERIFY:
if (!do_verify_init(jcr)) {
- verify_cleanup(jcr, JS_ErrorTerminated);
+ verify_cleanup(jcr, JS_ErrorTerminated);
}
break;
case JT_RESTORE:
if (!do_restore_init(jcr)) {
- restore_cleanup(jcr, JS_ErrorTerminated);
+ restore_cleanup(jcr, JS_ErrorTerminated);
}
break;
case JT_ADMIN:
if (!do_admin_init(jcr)) {
- admin_cleanup(jcr, JS_ErrorTerminated);
+ admin_cleanup(jcr, JS_ErrorTerminated);
}
break;
case JT_MIGRATION:
case JT_COPY:
case JT_ARCHIVE:
- if (!do_mac_init(jcr)) { /* migration, archive, copy */
- mac_cleanup(jcr, JS_ErrorTerminated);
+ if (!do_mac_init(jcr)) { /* migration, archive, copy */
+ mac_cleanup(jcr, JS_ErrorTerminated);
}
break;
default:
for ( ;; ) {
Dmsg0(200, "=====Start Job=========\n");
- jcr->start_time = time(NULL); /* set the real start time */
+ jcr->start_time = time(NULL); /* set the real start time */
jcr->jr.StartTime = jcr->start_time;
set_jcr_job_status(jcr, JS_Running);
if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
}
if (job_canceled(jcr)) {
- update_job_end_record(jcr);
+ update_job_end_record(jcr);
} else if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
- (utime_t)(jcr->start_time - jcr->sched_time)) {
+ (utime_t)(jcr->start_time - jcr->sched_time)) {
Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
- set_jcr_job_status(jcr, JS_Canceled);
- update_job_end_record(jcr);
+ set_jcr_job_status(jcr, JS_Canceled);
+ update_job_end_record(jcr);
} else {
- /* Run Job */
+ /* Run Job */
generate_event(jcr, "StartJob");
- if (jcr->job->RunBeforeJob) {
- POOLMEM *before = get_pool_memory(PM_FNAME);
- int status;
- BPIPE *bpipe;
- char line[MAXSTRING];
+ if (jcr->job->RunBeforeJob) {
+ POOLMEM *before = get_pool_memory(PM_FNAME);
+ int status;
+ BPIPE *bpipe;
+ char line[MAXSTRING];
before = edit_job_codes(jcr, before, jcr->job->RunBeforeJob, "");
bpipe = open_bpipe(before, 0, "r");
- free_pool_memory(before);
- while (fgets(line, sizeof(line), bpipe->rfd)) {
+ free_pool_memory(before);
+ while (fgets(line, sizeof(line), bpipe->rfd)) {
Jmsg(jcr, M_INFO, 0, _("RunBefore: %s"), line);
- }
- status = close_bpipe(bpipe);
- if (status != 0) {
- berrno be;
+ }
+ status = close_bpipe(bpipe);
+ if (status != 0) {
+ berrno be;
Jmsg(jcr, M_FATAL, 0, _("RunBeforeJob error: ERR=%s\n"), be.strerror(status));
- set_jcr_job_status(jcr, JS_FatalError);
- update_job_end_record(jcr);
- goto bail_out;
- }
- }
- switch (jcr->JobType) {
- case JT_BACKUP:
- if (do_backup(jcr)) {
- do_autoprune(jcr);
- } else {
- backup_cleanup(jcr, JS_ErrorTerminated);
- }
- break;
- case JT_VERIFY:
- if (do_verify(jcr)) {
- do_autoprune(jcr);
- } else {
- verify_cleanup(jcr, JS_ErrorTerminated);
- }
- break;
- case JT_RESTORE:
- if (do_restore(jcr)) {
- do_autoprune(jcr);
- } else {
- restore_cleanup(jcr, JS_ErrorTerminated);
- }
- break;
- case JT_ADMIN:
- if (do_admin(jcr)) {
- do_autoprune(jcr);
- } else {
- admin_cleanup(jcr, JS_ErrorTerminated);
- }
- break;
- case JT_MIGRATION:
- case JT_COPY:
- case JT_ARCHIVE:
- if (do_mac(jcr)) { /* migration, archive, copy */
- do_autoprune(jcr);
- } else {
- mac_cleanup(jcr, JS_ErrorTerminated);
- }
- break;
- default:
+ set_jcr_job_status(jcr, JS_FatalError);
+ update_job_end_record(jcr);
+ goto bail_out;
+ }
+ }
+ switch (jcr->JobType) {
+ case JT_BACKUP:
+ if (do_backup(jcr)) {
+ do_autoprune(jcr);
+ } else {
+ backup_cleanup(jcr, JS_ErrorTerminated);
+ }
+ break;
+ case JT_VERIFY:
+ if (do_verify(jcr)) {
+ do_autoprune(jcr);
+ } else {
+ verify_cleanup(jcr, JS_ErrorTerminated);
+ }
+ break;
+ case JT_RESTORE:
+ if (do_restore(jcr)) {
+ do_autoprune(jcr);
+ } else {
+ restore_cleanup(jcr, JS_ErrorTerminated);
+ }
+ break;
+ case JT_ADMIN:
+ if (do_admin(jcr)) {
+ do_autoprune(jcr);
+ } else {
+ admin_cleanup(jcr, JS_ErrorTerminated);
+ }
+ break;
+ case JT_MIGRATION:
+ case JT_COPY:
+ case JT_ARCHIVE:
+ if (do_mac(jcr)) { /* migration, archive, copy */
+ do_autoprune(jcr);
+ } else {
+ mac_cleanup(jcr, JS_ErrorTerminated);
+ }
+ break;
+ default:
Pmsg1(0, "Unimplemented job type: %d\n", jcr->JobType);
- break;
- }
- if ((jcr->job->RunAfterJob && jcr->JobStatus == JS_Terminated) ||
- (jcr->job->RunAfterFailedJob && jcr->JobStatus != JS_Terminated)) {
- POOLMEM *after = get_pool_memory(PM_FNAME);
- int status;
- BPIPE *bpipe;
- char line[MAXSTRING];
-
- if (jcr->JobStatus == JS_Terminated) {
+ break;
+ }
+ if ((jcr->job->RunAfterJob && jcr->JobStatus == JS_Terminated) ||
+ (jcr->job->RunAfterFailedJob && jcr->JobStatus != JS_Terminated)) {
+ POOLMEM *after = get_pool_memory(PM_FNAME);
+ int status;
+ BPIPE *bpipe;
+ char line[MAXSTRING];
+
+ if (jcr->JobStatus == JS_Terminated) {
after = edit_job_codes(jcr, after, jcr->job->RunAfterJob, "");
- } else {
+ } else {
after = edit_job_codes(jcr, after, jcr->job->RunAfterFailedJob, "");
- }
+ }
bpipe = open_bpipe(after, 0, "r");
- free_pool_memory(after);
- while (fgets(line, sizeof(line), bpipe->rfd)) {
+ free_pool_memory(after);
+ while (fgets(line, sizeof(line), bpipe->rfd)) {
Jmsg(jcr, M_INFO, 0, _("RunAfter: %s"), line);
- }
- status = close_bpipe(bpipe);
- /*
- * Note, if we get an error here, do not mark the
- * job in error, simply report the error condition.
- */
- if (status != 0) {
- berrno be;
- if (jcr->JobStatus == JS_Terminated) {
+ }
+ status = close_bpipe(bpipe);
+ /*
+ * Note, if we get an error here, do not mark the
+ * job in error, simply report the error condition.
+ */
+ if (status != 0) {
+ berrno be;
+ if (jcr->JobStatus == JS_Terminated) {
Jmsg(jcr, M_WARNING, 0, _("RunAfterJob error: ERR=%s\n"), be.strerror(status));
- } else {
+ } else {
Jmsg(jcr, M_FATAL, 0, _("RunAfterFailedJob error: ERR=%s\n"), be.strerror(status));
- }
- }
- }
+ }
+ }
+ }
generate_event(jcr, "EndJob");
- /* Send off any queued messages */
- if (jcr->msg_queue->size() > 0) {
- dequeue_messages(jcr);
- }
+ /* Send off any queued messages */
+ if (jcr->msg_queue->size() > 0) {
+ dequeue_messages(jcr);
+ }
}
bail_out:
break;
/*
* Cancel a job -- typically called by the UA (Console program), but may also
- * be called by the job watchdog.
+ * be called by the job watchdog.
*
* Returns: 1 if cancel appears to be successful
- * 0 on failure. Message sent to ua->jcr.
+ * 0 on failure. Message sent to ua->jcr.
*/
int cancel_job(UAContext *ua, JCR *jcr)
{
case JS_WaitStartTime:
set_jcr_job_status(jcr, JS_Canceled);
bsendmsg(ua, _("JobId %d, Job %s marked to be canceled.\n"),
- jcr->JobId, jcr->Job);
+ jcr->JobId, jcr->Job);
jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */
return 1;
/* Cancel File daemon */
if (jcr->file_bsock) {
- ua->jcr->client = jcr->client;
- if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) {
+ ua->jcr->client = jcr->client;
+ if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) {
bsendmsg(ua, _("Failed to connect to File daemon.\n"));
- return 0;
- }
+ return 0;
+ }
Dmsg0(200, "Connected to file daemon\n");
- fd = ua->jcr->file_bsock;
+ fd = ua->jcr->file_bsock;
bnet_fsend(fd, "cancel Job=%s\n", jcr->Job);
- while (bnet_recv(fd) >= 0) {
+ while (bnet_recv(fd) >= 0) {
bsendmsg(ua, "%s", fd->msg);
- }
- bnet_sig(fd, BNET_TERMINATE);
- bnet_close(fd);
- ua->jcr->file_bsock = NULL;
+ }
+ bnet_sig(fd, BNET_TERMINATE);
+ bnet_close(fd);
+ ua->jcr->file_bsock = NULL;
}
/* Cancel Storage daemon */
if (jcr->store_bsock) {
- if (!ua->jcr->storage) {
- copy_storage(ua->jcr, jcr);
- } else {
- set_storage(ua->jcr, jcr->store);
- }
- if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
+ if (!ua->jcr->storage) {
+ copy_storage(ua->jcr, jcr);
+ } else {
+ set_storage(ua->jcr, jcr->store);
+ }
+ if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
- return 0;
- }
+ return 0;
+ }
Dmsg0(200, "Connected to storage daemon\n");
- sd = ua->jcr->store_bsock;
+ sd = ua->jcr->store_bsock;
bnet_fsend(sd, "cancel Job=%s\n", jcr->Job);
- while (bnet_recv(sd) >= 0) {
+ while (bnet_recv(sd) >= 0) {
bsendmsg(ua, "%s", sd->msg);
- }
- bnet_sig(sd, BNET_TERMINATE);
- bnet_close(sd);
- ua->jcr->store_bsock = NULL;
+ }
+ bnet_sig(sd, BNET_TERMINATE);
+ bnet_close(sd);
+ ua->jcr->store_bsock = NULL;
}
}
if (jcr->JobId == 0) {
Dmsg2(800, "Skipping JCR %p (%s) with JobId 0\n",
- jcr, jcr->Job);
- /* Keep reference counts correct */
- free_locked_jcr(jcr);
- continue;
+ jcr, jcr->Job);
+ /* Keep reference counts correct */
+ free_locked_jcr(jcr);
+ continue;
}
/* check MaxWaitTime */
if (cancel) {
Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n",
- jcr, jcr->JobId, jcr->Job);
+ jcr, jcr->JobId, jcr->Job);
- UAContext *ua = new_ua_context(jcr);
- ua->jcr = control_jcr;
- cancel_job(ua, jcr);
- free_ua_context(ua);
+ UAContext *ua = new_ua_context(jcr);
+ ua->jcr = control_jcr;
+ cancel_job(ua, jcr);
+ free_ua_context(ua);
Dmsg1(800, "Have cancelled JCR %p\n", jcr);
}
return false;
}
if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
+ (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
ok_to_cancel = true;
} else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
+ (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
ok_to_cancel = true;
} else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
+ (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
ok_to_cancel = true;
} else if (job->MaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
+ (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
ok_to_cancel = true;
}
if (!ok_to_cancel) {
}
Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
"checking status\n",
- jcr->JobId, jcr->Job, job->MaxWaitTime);
+ jcr->JobId, jcr->Job, job->MaxWaitTime);
switch (jcr->JobStatus) {
case JS_Created:
case JS_Blocked:
case JS_WaitMount:
case JS_WaitMedia:
case JS_WaitFD:
- cancel = true;
+ cancel = true;
Dmsg0(800, "JCR blocked in #2\n");
- break;
+ break;
default:
Dmsg0(800, "JCR not blocked in #2\n");
- break;
+ break;
}
break;
case JS_Terminated:
break;
default:
Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
- jcr->JobStatus);
+ jcr->JobStatus);
}
Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
cancel ? "" : "do not ", jcr, jcr->job);
}
if ((watchdog_time - jcr->start_time) < jcr->job->MaxRunTime) {
Dmsg3(200, "Job %p (%s) with MaxRunTime %d not expired\n",
- jcr, jcr->Job, jcr->job->MaxRunTime);
+ jcr, jcr->Job, jcr->job->MaxRunTime);
return false;
}
break;
default:
Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
- jcr->JobStatus);
+ jcr->JobStatus);
}
Dmsg3(200, "MaxRunTime result: %scancel JCR %p (%s)\n",
pm_strcpy(jcr->client_name, jcr->client->hdr.name);
if (!db_create_client_record(jcr, jcr->db, &cr)) {
Jmsg(jcr, M_FATAL, 0, _("Could not create Client record. ERR=%s\n"),
- db_strerror(jcr->db));
+ db_strerror(jcr->db));
return false;
}
jcr->jr.ClientId = cr.ClientId;
if (cr.Uname[0]) {
if (!jcr->client_uname) {
- jcr->client_uname = get_pool_memory(PM_NAME);
+ jcr->client_uname = get_pool_memory(PM_NAME);
}
pm_strcpy(jcr->client_uname, cr.Uname);
}
!db_get_fileset_record(jcr, jcr->db, fsr)) {
if (!db_create_fileset_record(jcr, jcr->db, fsr)) {
Jmsg(jcr, M_ERROR, 0, _("Could not create FileSet \"%s\" record. ERR=%s\n"),
- fsr->FileSet, db_strerror(jcr->db));
- return false;
+ fsr->FileSet, db_strerror(jcr->db));
+ return false;
}
}
jcr->jr.FileSetId = fsr->FileSetId;
- if (fsr->created) {
+ if (fsr->created && jcr != NULL) {
Jmsg(jcr, M_INFO, 0, _("Created new FileSet record \"%s\" %s\n"),
- fsr->FileSet, fsr->cCreateTime);
+ fsr->FileSet, fsr->cCreateTime);
}
Dmsg2(119, "Created FileSet %s record %u\n", jcr->fileset->hdr.name,
jcr->jr.FileSetId);
{
jcr->jr.SchedTime = jcr->sched_time;
jcr->jr.StartTime = jcr->start_time;
- jcr->jr.EndTime = 0; /* perhaps rescheduled, clear it */
+ jcr->jr.EndTime = 0; /* perhaps rescheduled, clear it */
jcr->jr.JobType = jcr->JobType;
jcr->jr.JobLevel = jcr->JobLevel;
jcr->jr.JobStatus = jcr->JobStatus;
jcr->jr.VolSessionTime = jcr->VolSessionTime;
if (!db_update_job_end_record(jcr, jcr->db, &jcr->jr)) {
Jmsg(jcr, M_WARNING, 0, _("Error updating job record. %s"),
- db_strerror(jcr->db));
+ db_strerror(jcr->db));
}
}
/* Guarantee unique start time -- maximum one per second, and
* thus unique Job Name
*/
- P(mutex); /* lock creation of jobs */
+ P(mutex); /* lock creation of jobs */
now = time(NULL);
while (now == last_start_time) {
bmicrosleep(0, 500000);
now = time(NULL);
}
last_start_time = now;
- V(mutex); /* allow creation of jobs */
+ V(mutex); /* allow creation of jobs */
jcr->start_time = now;
/* Form Unique JobName */
localtime_r(&now, &tm);
/* Use only characters that are permitted in Windows filenames */
strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
bstrncpy(name, base_name, sizeof(name));
- name[sizeof(name)-22] = 0; /* truncate if too long */
+ name[sizeof(name)-22] = 0; /* truncate if too long */
bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s", name, dt); /* add date & time */
/* Convert spaces into underscores */
for (p=jcr->Job; *p; p++) {
/* Copy storage definitions -- deleted in dir_free_jcr above */
if (job->storage) {
if (jcr->storage) {
- delete jcr->storage;
+ delete jcr->storage;
}
jcr->storage = New(alist(10, not_owned_by_alist));
foreach_alist(st, job->storage) {
- jcr->storage->append(st);
+ jcr->storage->append(st);
}
}
if (jcr->storage) {
if (jcr->JobLevel == 0) {
switch (jcr->JobType) {
case JT_VERIFY:
- jcr->JobLevel = L_VERIFY_CATALOG;
- break;
+ jcr->JobLevel = L_VERIFY_CATALOG;
+ break;
case JT_BACKUP:
- jcr->JobLevel = L_INCREMENTAL;
- break;
+ jcr->JobLevel = L_INCREMENTAL;
+ break;
case JT_RESTORE:
case JT_ADMIN:
- jcr->JobLevel = L_NONE;
- break;
+ jcr->JobLevel = L_NONE;
+ break;
default:
- break;
+ break;
}
}
}
if (old_jcr->storage) {
STORE *st;
if (old_jcr->storage) {
- delete old_jcr->storage;
+ delete old_jcr->storage;
}
new_jcr->storage = New(alist(10, not_owned_by_alist));
foreach_alist(st, old_jcr->storage) {
- new_jcr->storage->append(st);
+ new_jcr->storage->append(st);
}
}
if (old_jcr->store) {
jcr->store = store;
foreach_alist(storage, jcr->storage) {
if (store == storage) {
- return;
+ return;
}
}
/* Store not in list, so add it */
#undef _POSIX_C_SOURCE
#include <Python.h>
+extern JCR *get_jcr_from_PyObject(PyObject *self);
+
PyObject *bacula_get(PyObject *self, PyObject *args);
PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw);
PyObject *bacula_run(PyObject *self, PyObject *args);
{"set", (PyCFunction)bacula_set, METH_VARARGS|METH_KEYWORDS,
"Set Bacula variables."},
{"run", (PyCFunction)bacula_run, METH_VARARGS, "Run a Bacula command."},
- {NULL, NULL, 0, NULL} /* last item */
+ {NULL, NULL, 0, NULL} /* last item */
};
{ N_("JobName"), "s"},
{ N_("JobStatus"), "s"},
- { NULL, NULL}
+ { NULL, NULL}
};
/* Return Bacula variables */
PyObject *bacula_get(PyObject *self, PyObject *args)
{
- PyObject *CObject;
JCR *jcr;
char *item;
bool found = false;
int i;
char buf[10];
- if (!PyArg_ParseTuple(args, "Os:get", &CObject, &item)) {
+ if (!PyArg_ParseTuple(args, "s:get", &item)) {
return NULL;
}
- jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
+ jcr = get_jcr_from_PyObject(self);
for (i=0; vars[i].name; i++) {
if (strcmp(vars[i].name, item) == 0) {
- found = true;
- break;
+ found = true;
+ break;
}
}
if (!found) {
return NULL;
}
switch (i) {
- case 0: /* Job */
+ case 0: /* Job */
return Py_BuildValue(vars[i].fmt, jcr->job->hdr.name);
case 1: /* Director's name */
return Py_BuildValue(vars[i].fmt, my_name);
- case 2: /* level */
+ case 2: /* level */
return Py_BuildValue(vars[i].fmt, job_level_to_str(jcr->JobLevel));
- case 3: /* type */
+ case 3: /* type */
return Py_BuildValue(vars[i].fmt, job_type_to_str(jcr->JobType));
- case 4: /* JobId */
+ case 4: /* JobId */
return Py_BuildValue(vars[i].fmt, jcr->JobId);
- case 5: /* Client */
+ case 5: /* Client */
return Py_BuildValue(vars[i].fmt, jcr->client->hdr.name);
- case 6: /* NumVols */
+ case 6: /* NumVols */
return Py_BuildValue(vars[i].fmt, jcr->NumVols);
- case 7: /* Pool */
+ case 7: /* Pool */
return Py_BuildValue(vars[i].fmt, jcr->pool->hdr.name);
- case 8: /* Storage */
+ case 8: /* Storage */
return Py_BuildValue(vars[i].fmt, jcr->store->hdr.name);
case 9:
return Py_BuildValue(vars[i].fmt, jcr->catalog->hdr.name);
- case 10: /* MediaType */
+ case 10: /* MediaType */
return Py_BuildValue(vars[i].fmt, jcr->store->media_type);
- case 11: /* JobName */
+ case 11: /* JobName */
return Py_BuildValue(vars[i].fmt, jcr->Job);
- case 12: /* JobStatus */
+ case 12: /* JobStatus */
buf[1] = 0;
buf[0] = jcr->JobStatus;
return Py_BuildValue(vars[i].fmt, buf);
/* Set Bacula variables */
PyObject *bacula_set(PyObject *self, PyObject *args, PyObject *keyw)
{
- PyObject *CObject;
JCR *jcr;
char *msg = NULL;
char *VolumeName = NULL;
- static char *kwlist[] = {"jcr", "JobReport", "VolumeName", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, keyw, "O|ss:set", kwlist,
- &CObject, &msg, &VolumeName)) {
+ static char *kwlist[] = {"JobReport", "VolumeName", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, keyw, "|ss:set", kwlist,
+ &msg, &VolumeName)) {
return NULL;
}
- jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
+ jcr = get_jcr_from_PyObject(self);
if (msg) {
Jmsg(jcr, M_INFO, 0, "%s", msg);
}
if (VolumeName) {
if (is_volume_name_legal(NULL, VolumeName)) {
- pm_strcpy(jcr->VolumeName, VolumeName);
+ pm_strcpy(jcr->VolumeName, VolumeName);
} else {
return Py_BuildValue("i", 0); /* invalid volume name */
}
/* Run a Bacula command */
PyObject *bacula_run(PyObject *self, PyObject *args)
{
- PyObject *CObject;
JCR *jcr;
char *item;
int stat;
- if (!PyArg_ParseTuple(args, "Os:get", &CObject, &item)) {
+ if (!PyArg_ParseTuple(args, "s:get", &item)) {
return NULL;
}
- jcr = (JCR *)PyCObject_AsVoidPtr(CObject);
+ jcr = get_jcr_from_PyObject(self);
UAContext *ua = new_ua_context(jcr);
ua->batch = true;
- pm_strcpy(ua->cmd, item); /* copy command */
- parse_ua_args(ua); /* parse command */
+ pm_strcpy(ua->cmd, item); /* copy command */
+ parse_ua_args(ua); /* parse command */
stat = run_cmd(ua, ua->cmd);
free_ua_context(ua);
return Py_BuildValue("i", stat);
DEBUG=@DEBUG@
+PYTHON_LIBS = @PYTHON_LIBS@
+PYTHON_INC = @PYTHON_INCDIR@
+
first_rule: all
dummy:
/*
- * Bacula File Daemon backup.c send file attributes and data
+ * Bacula File Daemon backup.c send file attributes and data
* to the Storage daemon.
*
* Kern Sibbald, March MM
#include "filed.h"
/* Forward referenced functions */
-static int save_file(FF_PKT *ff_pkt, void *pkt);
+static int save_file(FF_PKT *ff_pkt, void *pkt, bool top_level);
static int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, struct CHKSUM *chksum);
static bool encode_and_send_attributes(JCR *jcr, FF_PKT *ff_pkt, int &data_stream);
static bool read_and_send_acl(JCR *jcr, int acltype, int stream);
if (client) {
buf_size = client->max_network_buffer_size;
} else {
- buf_size = 0; /* use default */
+ buf_size = 0; /* use default */
}
if (!bnet_set_buffer_size(sd, buf_size, BNET_SETBUF_WRITE)) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
/* Subroutine save_file() is called for each file */
if (!find_files(jcr, (FF_PKT *)jcr->ff, save_file, (void *)jcr)) {
- ok = false; /* error */
+ ok = false; /* error */
set_jcr_job_status(jcr, JS_ErrorTerminated);
// Jmsg(jcr, M_FATAL, 0, _("Find files error.\n"));
}
stop_heartbeat_monitor(jcr);
- bnet_sig(sd, BNET_EOD); /* end data connection */
+ bnet_sig(sd, BNET_EOD); /* end data connection */
if (jcr->big_buf) {
free(jcr->big_buf);
* Send the file and its data to the Storage daemon.
*
* Returns: 1 if OK
- * 0 if error
- * -1 to ignore file/directory (not used here)
+ * 0 if error
+ * -1 to ignore file/directory (not used here)
*/
-static int save_file(FF_PKT *ff_pkt, void *vjcr)
+static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level)
{
int stat, data_stream;
struct CHKSUM chksum;
}
sd = jcr->store_bsock;
- jcr->num_files_examined++; /* bump total file count */
+ jcr->num_files_examined++; /* bump total file count */
switch (ff_pkt->type) {
- case FT_LNKSAVED: /* Hard linked, file already saved */
+ case FT_LNKSAVED: /* Hard linked, file already saved */
Dmsg2(130, "FT_LNKSAVED hard link: %s => %s\n", ff_pkt->fname, ff_pkt->link);
break;
case FT_REGE:
Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
break;
case FT_DIRBEGIN:
- return 1; /* not used */
+ return 1; /* not used */
case FT_NORECURSE:
case FT_NOFSCHG:
case FT_INVALIDFS:
case FT_DIREND:
if (ff_pkt->type == FT_NORECURSE) {
Jmsg(jcr, M_INFO, 1, _(" Recursion turned off. Will not descend into %s\n"),
- ff_pkt->fname);
+ ff_pkt->fname);
} else if (ff_pkt->type == FT_NOFSCHG) {
Jmsg(jcr, M_INFO, 1, _(" File system change prohibited. Will not descend into %s\n"),
- ff_pkt->fname);
+ ff_pkt->fname);
} else if (ff_pkt->type == FT_INVALIDFS) {
Jmsg(jcr, M_INFO, 1, _(" Disallowed filesystem. Will not descend into %s\n"),
- ff_pkt->fname);
+ ff_pkt->fname);
}
ff_pkt->type = FT_DIREND; /* value is used below */
Dmsg1(130, "FT_DIR saving: %s\n", ff_pkt->link);
case FT_NOACCESS: {
berrno be;
Jmsg(jcr, M_NOTSAVED, 0, _(" Could not access %s: ERR=%s\n"), ff_pkt->fname,
- be.strerror(ff_pkt->ff_errno));
+ be.strerror(ff_pkt->ff_errno));
jcr->Errors++;
return 1;
}
case FT_NOFOLLOW: {
berrno be;
Jmsg(jcr, M_NOTSAVED, 0, _(" Could not follow link %s: ERR=%s\n"), ff_pkt->fname,
- be.strerror(ff_pkt->ff_errno));
+ be.strerror(ff_pkt->ff_errno));
jcr->Errors++;
return 1;
}
case FT_NOSTAT: {
berrno be;
Jmsg(jcr, M_NOTSAVED, 0, _(" Could not stat %s: ERR=%s\n"), ff_pkt->fname,
- be.strerror(ff_pkt->ff_errno));
+ be.strerror(ff_pkt->ff_errno));
jcr->Errors++;
return 1;
}
case FT_NOOPEN: {
berrno be;
Jmsg(jcr, M_NOTSAVED, 0, _(" Could not open directory %s: ERR=%s\n"), ff_pkt->fname,
- be.strerror(ff_pkt->ff_errno));
+ be.strerror(ff_pkt->ff_errno));
jcr->Errors++;
return 1;
}
* the BackupRead will save its permissions and ownership streams.
*/
if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
- ff_pkt->statp.st_size > 0) ||
- ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
- (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
+ ff_pkt->statp.st_size > 0) ||
+ ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO ||
+ (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) {
btimer_t *tid;
if (ff_pkt->type == FT_FIFO) {
- tid = start_thread_timer(pthread_self(), 60);
+ tid = start_thread_timer(pthread_self(), 60);
} else {
- tid = NULL;
+ tid = NULL;
}
if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
- ff_pkt->ff_errno = errno;
- berrno be;
+ ff_pkt->ff_errno = errno;
+ berrno be;
Jmsg(jcr, M_NOTSAVED, 0, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname,
- be.strerror());
- jcr->Errors++;
- if (tid) {
- stop_thread_timer(tid);
- tid = NULL;
- }
- return 1;
+ be.strerror());
+ jcr->Errors++;
+ if (tid) {
+ stop_thread_timer(tid);
+ tid = NULL;
+ }
+ return 1;
}
if (tid) {
- stop_thread_timer(tid);
- tid = NULL;
+ stop_thread_timer(tid);
+ tid = NULL;
}
stat = send_data(jcr, data_stream, ff_pkt, &chksum);
bclose(&ff_pkt->bfd);
if (!stat) {
- return 0;
+ return 0;
}
}
#ifdef HAVE_DARWIN_OS
/* Regular files can have resource forks and Finder Info */
if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
- ff_pkt->flags & FO_HFSPLUS)) {
+ ff_pkt->flags & FO_HFSPLUS)) {
if (ff_pkt->hfsinfo.rsrclength > 0) {
- int flags;
- if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
- ff_pkt->ff_errno = errno;
- berrno be;
+ int flags;
+ if (!bopen_rsrc(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
+ ff_pkt->ff_errno = errno;
+ berrno be;
Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for %s: ERR=%s.\n"), ff_pkt->fname,
- be.strerror());
- jcr->Errors++;
- if (is_bopen(&ff_pkt->bfd)) {
- bclose(&ff_pkt->bfd);
- }
- return 1;
- }
- flags = ff_pkt->flags;
- ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
- stat = send_data(jcr, STREAM_MACOS_FORK_DATA, ff_pkt, &chksum);
- ff_pkt->flags = flags;
- bclose(&ff_pkt->bfd);
- if (!stat) {
- return 0;
- }
+ be.strerror());
+ jcr->Errors++;
+ if (is_bopen(&ff_pkt->bfd)) {
+ bclose(&ff_pkt->bfd);
+ }
+ return 1;
+ }
+ flags = ff_pkt->flags;
+ ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
+ stat = send_data(jcr, STREAM_MACOS_FORK_DATA, ff_pkt, &chksum);
+ ff_pkt->flags = flags;
+ bclose(&ff_pkt->bfd);
+ if (!stat) {
+ return 0;
+ }
}
Dmsg1(300, "Saving Finder Info for \"%s\"\n", ff_pkt->fname);
if (ff_pkt->flags & FO_ACL) {
/* Read access ACLs for files, dirs and links */
if (!read_and_send_acl(jcr, BACL_TYPE_ACCESS, STREAM_UNIX_ATTRIBUTES_ACCESS_ACL)) {
- return 0;
+ return 0;
}
/* Directories can have default ACLs too */
if (ff_pkt->type == FT_DIREND && (BACL_CAP & BACL_CAP_DEFAULTS_DIR)) {
- if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) {
- return 0;
- }
+ if (!read_and_send_acl(jcr, BACL_TYPE_DEFAULT, STREAM_UNIX_ATTRIBUTES_DEFAULT_ACL)) {
+ return 0;
+ }
}
}
int stream = 0;
chksum_final(&chksum);
if (chksum.type == CHKSUM_MD5) {
- stream = STREAM_MD5_SIGNATURE;
+ stream = STREAM_MD5_SIGNATURE;
} else if (chksum.type == CHKSUM_SHA1) {
- stream = STREAM_SHA1_SIGNATURE;
+ stream = STREAM_SHA1_SIGNATURE;
} else {
Jmsg1(jcr, M_WARNING, 0, _("Unknown signature type %i.\n"), chksum.type);
}
if (stream != 0) {
bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream);
Dmsg1(300, "bfiled>stored:header %s\n", sd->msg);
- memcpy(sd->msg, chksum.signature, chksum.length);
- sd->msglen = chksum.length;
- bnet_send(sd);
- bnet_sig(sd, BNET_EOD); /* end of checksum */
+ memcpy(sd->msg, chksum.signature, chksum.length);
+ sd->msglen = chksum.length;
+ bnet_send(sd);
+ bnet_sig(sd, BNET_EOD); /* end of checksum */
}
}
int send_data(JCR *jcr, int stream, FF_PKT *ff_pkt, struct CHKSUM *chksum)
{
BSOCK *sd = jcr->store_bsock;
- uint64_t fileAddr = 0; /* file address */
+ uint64_t fileAddr = 0; /* file address */
char *rbuf, *wbuf;
- int rsize = jcr->buf_size; /* read buffer size */
+ int rsize = jcr->buf_size; /* read buffer size */
POOLMEM *msgsave;
msgsave = sd->msg;
- rbuf = sd->msg; /* read buffer */
- wbuf = sd->msg; /* write buffer */
+ rbuf = sd->msg; /* read buffer */
+ wbuf = sd->msg; /* write buffer */
Dmsg1(300, "Saving data, type=%d\n", ff_pkt->type);
if (ff_pkt->flags & FO_GZIP) {
if (ff_pkt->flags & FO_SPARSE) {
- cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
- max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
+ cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
+ max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
} else {
- cbuf = (Bytef *)jcr->compress_buf;
- max_compress_len = jcr->compress_buf_size; /* set max length */
+ cbuf = (Bytef *)jcr->compress_buf;
+ max_compress_len = jcr->compress_buf_size; /* set max length */
}
wbuf = jcr->compress_buf; /* compressed output here */
}
/*
* Send Data header to Storage daemon
- * <file-index> <stream> <info>
+ * <file-index> <stream> <info>
*/
if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return 0;
}
Dmsg1(300, ">stored: datahdr %s\n", sd->msg);
/*
* Make space at beginning of buffer for fileAddr because this
- * same buffer will be used for writing if compression if off.
+ * same buffer will be used for writing if compression if off.
*/
if (ff_pkt->flags & FO_SPARSE) {
rbuf += SPARSE_FADDR_SIZE;
/* Check for sparse blocks */
if (ff_pkt->flags & FO_SPARSE) {
- ser_declare;
- if (sd->msglen == rsize &&
- (fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size)) {
- sparseBlock = is_buf_zero(rbuf, rsize);
- }
-
- ser_begin(wbuf, SPARSE_FADDR_SIZE);
- ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
+ ser_declare;
+ if (sd->msglen == rsize &&
+ (fileAddr+sd->msglen < (uint64_t)ff_pkt->statp.st_size)) {
+ sparseBlock = is_buf_zero(rbuf, rsize);
+ }
+
+ ser_begin(wbuf, SPARSE_FADDR_SIZE);
+ ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
}
- jcr->ReadBytes += sd->msglen; /* count bytes read */
+ jcr->ReadBytes += sd->msglen; /* count bytes read */
fileAddr += sd->msglen;
/* Update checksum if requested */
#ifdef HAVE_LIBZ
/* Do compression if turned on */
if (!sparseBlock && ff_pkt->flags & FO_GZIP) {
- int zstat;
- compress_len = max_compress_len;
+ int zstat;
+ compress_len = max_compress_len;
Dmsg4(400, "cbuf=0x%x len=%u rbuf=0x%x len=%u\n", cbuf, compress_len,
- rbuf, sd->msglen);
- /* NOTE! This call modifies compress_len !!! */
- if ((zstat=compress2((Bytef *)cbuf, &compress_len,
- (const Bytef *)rbuf, (uLong)sd->msglen,
- ff_pkt->GZIP_level)) != Z_OK) {
+ rbuf, sd->msglen);
+ /* NOTE! This call modifies compress_len !!! */
+ if ((zstat=compress2((Bytef *)cbuf, &compress_len,
+ (const Bytef *)rbuf, (uLong)sd->msglen,
+ ff_pkt->GZIP_level)) != Z_OK) {
Jmsg(jcr, M_FATAL, 0, _("Compression error: %d\n"), zstat);
- sd->msg = msgsave;
- sd->msglen = 0;
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
- }
+ sd->msg = msgsave;
+ sd->msglen = 0;
+ set_jcr_job_status(jcr, JS_ErrorTerminated);
+ return 0;
+ }
Dmsg2(400, "compressed len=%d uncompressed len=%d\n",
- compress_len, sd->msglen);
+ compress_len, sd->msglen);
- sd->msglen = compress_len; /* set compressed length */
+ sd->msglen = compress_len; /* set compressed length */
}
#endif
/* Send the buffer to the Storage daemon */
if (!sparseBlock) {
- if (ff_pkt->flags & FO_SPARSE) {
- sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
- }
- sd->msg = wbuf; /* set correct write buffer */
- if (!bnet_send(sd)) {
+ if (ff_pkt->flags & FO_SPARSE) {
+ sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
+ }
+ 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));
- sd->msg = msgsave; /* restore bnet buffer */
- sd->msglen = 0;
- return 0;
- }
+ sd->msglen, bnet_strerror(sd));
+ sd->msg = msgsave; /* restore bnet buffer */
+ sd->msglen = 0;
+ return 0;
+ }
}
Dmsg1(130, "Send data to SD len=%d\n", sd->msglen);
- /* #endif */
- jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed */
- sd->msg = msgsave; /* restore read buffer */
+ /* #endif */
+ jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed */
+ sd->msg = msgsave; /* restore read buffer */
} /* end while read file data */
if (sd->msglen < 0) {
berrno be;
Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"),
- ff_pkt->fname, be.strerror(ff_pkt->bfd.berrno));
+ ff_pkt->fname, be.strerror(ff_pkt->bfd.berrno));
}
- if (!bnet_sig(sd, BNET_EOD)) { /* indicate end of file data */
+ if (!bnet_sig(sd, BNET_EOD)) { /* indicate end of file data */
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return 0;
}
return true;
}
if (len == 0) {
- return true; /* no ACL */
+ return true; /* no ACL */
}
/* Send header */
if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return false;
}
sd->msg = msgsave;
sd->msglen = 0;
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return false;
}
sd->msg = msgsave;
if (!bnet_sig(sd, BNET_EOD)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return false;
}
Dmsg3(300, "File %s\nattribs=%s\nattribsEx=%s\n", ff_pkt->fname, attribs, attribsEx);
P(jcr->mutex);
- jcr->JobFiles++; /* increment number of files sent */
+ jcr->JobFiles++; /* increment number of files sent */
ff_pkt->FileIndex = jcr->JobFiles; /* return FileIndex */
pm_strcpy(jcr->last_fname, ff_pkt->fname);
V(jcr->mutex);
/*
* Send Attributes header to Storage daemon
- * <file-index> <stream> <info>
+ * <file-index> <stream> <info>
*/
if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, attr_stream)) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return false;
}
Dmsg1(300, ">stored: attrhdr %s\n", sd->msg);
/*
* Send file attributes to Storage daemon
- * File_index
- * File type
- * Filename (full path)
- * Encoded attributes
- * Link name (if type==FT_LNK or FT_LNKSAVED)
- * Encoded extended-attributes (for Win32)
+ * File_index
+ * File type
+ * Filename (full path)
+ * Encoded attributes
+ * Link name (if type==FT_LNK or FT_LNKSAVED)
+ * Encoded extended-attributes (for Win32)
*
* For a directory, link is the same as fname, but with trailing
* slash. For a linked file, link is the link.
if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
Dmsg2(300, "Link %s to %s\n", ff_pkt->fname, ff_pkt->link);
stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles,
- ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
- attribsEx, 0);
+ ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0,
+ attribsEx, 0);
} else if (ff_pkt->type == FT_DIREND) {
/* Here link is the canonical filename (i.e. with trailing slash) */
stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
- ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
+ ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0);
} else {
stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles,
- ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
+ ff_pkt->type, ff_pkt->fname, 0, attribs, 0, 0, attribsEx, 0);
}
Dmsg2(300, ">stored: attr len=%d: %s\n", sd->msglen, sd->msg);
if (!stat) {
Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- bnet_strerror(sd));
+ bnet_strerror(sd));
return false;
}
- bnet_sig(sd, BNET_EOD); /* indicate end of attributes data */
+ bnet_sig(sd, BNET_EOD); /* indicate end of attributes data */
return true;
}
#include "bacula.h"
#include "filed.h"
-static int tally_file(FF_PKT *ff_pkt, void *pkt);
+static int tally_file(FF_PKT *ff_pkt, void *pkt, bool);
/*
* Find all the requested files and count them.
* Called here by find() for each file included.
*
*/
-static int tally_file(FF_PKT *ff_pkt, void *ijcr)
+static int tally_file(FF_PKT *ff_pkt, void *ijcr, bool top_level)
{
JCR *jcr = (JCR *)ijcr;
ATTR attr;
return 0;
}
switch (ff_pkt->type) {
- case FT_LNKSAVED: /* Hard linked, file already saved */
+ case FT_LNKSAVED: /* Hard linked, file already saved */
case FT_REGE:
case FT_REG:
case FT_LNK:
if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode)) {
if (ff_pkt->statp.st_size > 0) {
- jcr->JobBytes += ff_pkt->statp.st_size;
+ jcr->JobBytes += ff_pkt->statp.st_size;
}
#ifdef HAVE_DARWIN_OS
if (ff_pkt->flags & FO_HFSPLUS) {
- if (ff_pkt->hfsinfo.rsrclength > 0) {
- jcr->JobBytes += ff_pkt->hfsinfo.rsrclength;
- }
- jcr->JobBytes += 32; /* Finder info */
+ if (ff_pkt->hfsinfo.rsrclength > 0) {
+ jcr->JobBytes += ff_pkt->hfsinfo.rsrclength;
+ }
+ jcr->JobBytes += 32; /* Finder info */
}
#endif
}
jcr->num_files_examined++;
- jcr->JobFiles++; /* increment number of files seen */
+ jcr->JobFiles++; /* increment number of files seen */
if (jcr->listing) {
memcpy(&attr.statp, &ff_pkt->statp, sizeof(struct stat));
attr.type = ff_pkt->type;
void terminate_filed(int sig);
/* Exported variables */
-CLIENT *me; /* my resource */
+CLIENT *me; /* my resource */
char OK_msg[] = "2000 OK\n";
char TERM_msg[] = "2999 Terminate\n";
bool no_signals = false;
static char *configfile = NULL;
static bool foreground = false;
static bool inetd_request = false;
-static workq_t dir_workq; /* queue of work from Director */
+static workq_t dir_workq; /* queue of work from Director */
static pthread_t server_tid;
while ((ch = getopt(argc, argv, "c:d:fg:istu:v?")) != -1) {
switch (ch) {
case 'c': /* configuration file */
- if (configfile != NULL) {
- free(configfile);
- }
- configfile = bstrdup(optarg);
- break;
+ if (configfile != NULL) {
+ free(configfile);
+ }
+ configfile = bstrdup(optarg);
+ break;
case 'd': /* debug level */
- debug_level = atoi(optarg);
- if (debug_level <= 0) {
- debug_level = 1;
- }
- break;
+ debug_level = atoi(optarg);
+ if (debug_level <= 0) {
+ debug_level = 1;
+ }
+ break;
case 'f': /* run in foreground */
- foreground = true;
- break;
+ foreground = true;
+ break;
case 'g': /* set group */
- gid = optarg;
- break;
+ gid = optarg;
+ break;
case 'i':
- inetd_request = true;
- break;
+ inetd_request = true;
+ break;
case 's':
- no_signals = true;
- break;
+ no_signals = true;
+ break;
case 't':
- test_config = true;
- break;
+ test_config = true;
+ break;
case 'u': /* set userid */
- uid = optarg;
- break;
+ uid = optarg;
+ break;
case 'v': /* verbose */
- verbose++;
- break;
+ verbose++;
+ break;
case '?':
default:
- usage();
+ usage();
}
}
if (argc) {
if (configfile != NULL)
- free(configfile);
+ free(configfile);
configfile = bstrdup(*argv);
argc--;
argv++;
UnlockRes();
if (!director) {
Emsg1(M_ABORT, 0, _("No Director resource defined in %s\n"),
- configfile);
+ configfile);
}
LockRes();
} else {
my_name_is(0, NULL, me->hdr.name);
if (!me->messages) {
- LockRes();
- me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
- UnlockRes();
- if (!me->messages) {
+ LockRes();
+ me->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
+ UnlockRes();
+ if (!me->messages) {
Emsg1(M_ABORT, 0, _("No Messages resource defined in %s\n"), configfile);
- }
+ }
}
- close_msg(NULL); /* close temp message handler */
+ close_msg(NULL); /* close temp message handler */
init_msg(NULL, me->messages); /* open user specified message handler */
}
if (!foreground &&!inetd_request) {
daemon_start();
- init_stack_dump(); /* set new pid */
+ init_stack_dump(); /* set new pid */
}
/* Maximum 1 daemon at a time */
me += 1000000;
#endif
+ init_python_interpreter(me->hdr.name, me->scripts_directory ?
+ me->scripts_directory : ".");
+
set_thread_concurrency(10);
if (!no_signals) {
- start_watchdog(); /* start watchdog thread */
- init_jcr_subsystem(); /* start JCR watchdogs etc. */
+ start_watchdog(); /* start watchdog thread */
+ init_jcr_subsystem(); /* start JCR watchdogs etc. */
}
server_tid = pthread_self();
int port = -1;
socklen_t client_addr_len = sizeof(client_addr);
if (getsockname(0, &client_addr, &client_addr_len) == 0) {
- /* MA BUG 6 remove ifdefs */
- port = sockaddr_get_port_net_order(&client_addr);
+ /* MA BUG 6 remove ifdefs */
+ port = sockaddr_get_port_net_order(&client_addr);
}
BSOCK *bs = init_bsock(NULL, 0, "client", "unknown client", port, &client_addr);
handle_client_request((void *)bs);
}
terminate_filed(0);
- exit(0); /* should never get here */
+ exit(0); /* should never get here */
}
void terminate_filed(int sig)
free_config_resources();
term_msg();
stop_watchdog();
- close_memory_pool(); /* release free memory in pool */
- sm_dump(false); /* dump orphaned buffers */
+ close_memory_pool(); /* release free memory in pool */
+ sm_dump(false); /* dump orphaned buffers */
exit(sig);
}
* 1. The generic lexical scanner in lib/lex.c and lib/lex.h
*
* 2. The generic config scanner in lib/parse_config.c and
- * lib/parse_config.h.
- * These files contain the parser code, some utility
- * routines, and the common store routines (name, int,
- * string).
+ * lib/parse_config.h.
+ * These files contain the parser code, some utility
+ * routines, and the common store routines (name, int,
+ * string).
*
* 3. The daemon specific file, which contains the Resource
- * definitions as well as any specific store routines
- * for the resource records.
+ * definitions as well as any specific store routines
+ * for the resource records.
*
* Kern Sibbald, September MM
*
{"workingdirectory", store_dir, ITEM(res_client.working_directory), 0, ITEM_REQUIRED, 0},
{"piddirectory", store_dir, ITEM(res_client.pid_directory), 0, ITEM_REQUIRED, 0},
{"subsysdirectory", store_dir, ITEM(res_client.subsys_directory), 0, 0, 0},
+ {"scriptsdirectory", store_dir, ITEM(res_client.scripts_directory), 0, 0, 0},
{"requiressl", store_yesno, ITEM(res_client.require_ssl), 1, ITEM_DEFAULT, 0},
{"maximumconcurrentjobs", store_pint, ITEM(res_client.MaxConcurrentJobs), 0, ITEM_DEFAULT, 10},
{"messages", store_res, ITEM(res_client.messages), R_MSGS, 0, 0},
{"filedaemon", cli_items, R_CLIENT},
{"client", cli_items, R_CLIENT}, /* alias for filedaemon */
{"messages", msgs_items, R_MSGS},
- {NULL, NULL, 0}
+ {NULL, NULL, 0}
};
sendit(sock, "No record for %d %s\n", type, res_to_str(type));
return;
}
- if (type < 0) { /* no recursion */
+ if (type < 0) { /* no recursion */
type = - type;
recurse = 0;
}
switch (type) {
case R_DIRECTOR:
- sendit(sock, "Director: name=%s password=%s\n", reshdr->name,
- res->res_dir.password);
- break;
+ sendit(sock, "Director: name=%s password=%s\n", reshdr->name,
+ res->res_dir.password);
+ break;
case R_CLIENT:
- sendit(sock, "Client: name=%s FDport=%d\n", reshdr->name,
- get_first_port_host_order(res->res_client.FDaddrs));
- break;
+ sendit(sock, "Client: name=%s FDport=%d\n", reshdr->name,
+ get_first_port_host_order(res->res_client.FDaddrs));
+ break;
case R_MSGS:
- sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
- if (res->res_msgs.mail_cmd)
- sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd);
- if (res->res_msgs.operator_cmd)
- sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd);
- break;
+ sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
+ if (res->res_msgs.mail_cmd)
+ sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd);
+ if (res->res_msgs.operator_cmd)
+ sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd);
+ break;
default:
- sendit(sock, "Unknown resource type %d\n", type);
+ sendit(sock, "Unknown resource type %d\n", type);
}
if (recurse && res->res_dir.hdr.next)
dump_resource(type, res->res_dir.hdr.next, sendit, sock);
switch (type) {
case R_DIRECTOR:
if (res->res_dir.password) {
- free(res->res_dir.password);
+ free(res->res_dir.password);
}
if (res->res_dir.address) {
- free(res->res_dir.address);
+ free(res->res_dir.address);
}
break;
case R_CLIENT:
if (res->res_client.working_directory) {
- free(res->res_client.working_directory);
+ free(res->res_client.working_directory);
}
if (res->res_client.pid_directory) {
- free(res->res_client.pid_directory);
+ free(res->res_client.pid_directory);
}
if (res->res_client.subsys_directory) {
- free(res->res_client.subsys_directory);
+ free(res->res_client.subsys_directory);
}
if (res->res_client.FDaddrs) {
- free_addresses(res->res_client.FDaddrs);
+ free_addresses(res->res_client.FDaddrs);
}
break;
case R_MSGS:
if (res->res_msgs.mail_cmd)
- free(res->res_msgs.mail_cmd);
+ free(res->res_msgs.mail_cmd);
if (res->res_msgs.operator_cmd)
- free(res->res_msgs.operator_cmd);
+ free(res->res_msgs.operator_cmd);
free_msgs_res((MSGS *)res); /* free message resource */
res = NULL;
break;
*/
for (i=0; items[i].name; i++) {
if (items[i].flags & ITEM_REQUIRED) {
- if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
- Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
- items[i].name, resources[rindex]);
- }
+ if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
+ Emsg2(M_ABORT, 0, _("%s item is required in %s resource, but not found.\n"),
+ items[i].name, resources[rindex]);
+ }
}
}
*/
if (pass == 2) {
switch (type) {
- /* Resources not containing a resource */
- case R_MSGS:
- case R_DIRECTOR:
- break;
+ /* Resources not containing a resource */
+ case R_MSGS:
+ case R_DIRECTOR:
+ break;
- /* Resources containing another resource */
- case R_CLIENT:
- if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) {
- Emsg1(M_ABORT, 0, "Cannot find Client resource %s\n", res_all.res_dir.hdr.name);
- }
- res->res_client.messages = res_all.res_client.messages;
- break;
- default:
- Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type);
- error = 1;
- break;
+ /* Resources containing another resource */
+ case R_CLIENT:
+ if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_dir.hdr.name)) == NULL) {
+ Emsg1(M_ABORT, 0, "Cannot find Client resource %s\n", res_all.res_dir.hdr.name);
+ }
+ res->res_client.messages = res_all.res_client.messages;
+ break;
+ default:
+ Emsg1(M_ERROR, 0, _("Unknown resource type %d\n"), type);
+ error = 1;
+ break;
}
/* Note, the resoure name was already saved during pass 1,
* so here, we can just release it.
*/
if (res_all.res_dir.hdr.name) {
- free(res_all.res_dir.hdr.name);
- res_all.res_dir.hdr.name = NULL;
+ free(res_all.res_dir.hdr.name);
+ res_all.res_dir.hdr.name = NULL;
}
if (res_all.res_dir.hdr.desc) {
- free(res_all.res_dir.hdr.desc);
- res_all.res_dir.hdr.desc = NULL;
+ free(res_all.res_dir.hdr.desc);
+ res_all.res_dir.hdr.desc = NULL;
}
return;
}
/* The following code is only executed on pass 1 */
switch (type) {
case R_DIRECTOR:
- size = sizeof(DIRRES);
- break;
+ size = sizeof(DIRRES);
+ break;
case R_CLIENT:
- size = sizeof(CLIENT);
- break;
+ size = sizeof(CLIENT);
+ break;
case R_MSGS:
- size = sizeof(MSGS);
- break;
+ size = sizeof(MSGS);
+ break;
default:
- printf(_("Unknown resource type %d\n"), type);
- error = 1;
- size = 1;
- break;
+ printf(_("Unknown resource type %d\n"), type);
+ error = 1;
+ size = 1;
+ break;
}
/* Common */
if (!error) {
res = (URES *)malloc(size);
memcpy(res, &res_all, size);
if (!res_head[rindex]) {
- res_head[rindex] = (RES *)res; /* store first entry */
+ res_head[rindex] = (RES *)res; /* store first entry */
} else {
- RES *next;
- /* Add new res to end of chain */
- for (next=res_head[rindex]; next->next; next=next->next) {
- if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
- Emsg2(M_ERROR_TERM, 0,
- _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
- resources[rindex].name, res->res_dir.hdr.name);
- }
- }
- next->next = (RES *)res;
- Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
- res->res_dir.hdr.name);
+ RES *next;
+ /* Add new res to end of chain */
+ for (next=res_head[rindex]; next->next; next=next->next) {
+ if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+ Emsg2(M_ERROR_TERM, 0,
+ _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
+ resources[rindex].name, res->res_dir.hdr.name);
+ }
+ }
+ next->next = (RES *)res;
+ Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
+ res->res_dir.hdr.name);
}
}
}
char *working_directory;
char *pid_directory;
char *subsys_directory;
+ char *scripts_directory;
int require_ssl; /* Require SSL on all connections */
MSGS *messages; /* daemon message handler */
int MaxConcurrentJobs;
/*
- * Bacula File Daemon verify.c Verify files.
+ * Bacula File Daemon verify.c Verify files.
*
* Kern Sibbald, October MM
*
#include "bacula.h"
#include "filed.h"
-static int verify_file(FF_PKT *ff_pkt, void *my_pkt);
+static int verify_file(FF_PKT *ff_pkt, void *my_pkt, bool);
static int read_chksum(BFILE *bfd, CHKSUM *chksum, JCR *jcr);
/*
jcr->buf_size = DEFAULT_NETWORK_BUFFER_SIZE;
if ((jcr->big_buf = (char *) malloc(jcr->buf_size)) == NULL) {
Jmsg1(jcr, M_ABORT, 0, _("Cannot malloc %d network read buffer\n"),
- DEFAULT_NETWORK_BUFFER_SIZE);
+ DEFAULT_NETWORK_BUFFER_SIZE);
}
set_find_options((FF_PKT *)jcr->ff, jcr->incremental, jcr->mtime);
Dmsg0(10, "Start find files\n");
*
* Find the file, compute the MD5 or SHA1 and send it back to the Director
*/
-static int verify_file(FF_PKT *ff_pkt, void *pkt)
+static int verify_file(FF_PKT *ff_pkt, void *pkt, bool top_level)
{
char attribs[MAXSTRING];
char attribsEx[MAXSTRING];
}
dir = jcr->dir_bsock;
- jcr->num_files_examined++; /* bump total file count */
+ jcr->num_files_examined++; /* bump total file count */
switch (ff_pkt->type) {
- case FT_LNKSAVED: /* Hard linked, file already saved */
+ case FT_LNKSAVED: /* Hard linked, file already saved */
Dmsg2(30, "FT_LNKSAVED saving: %s => %s\n", ff_pkt->fname, ff_pkt->link);
break;
case FT_REGE:
Dmsg2(30, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link);
break;
case FT_DIRBEGIN:
- return 1; /* ignored */
+ return 1; /* ignored */
case FT_DIREND:
Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname);
break;
encode_attribsEx(jcr, attribsEx, ff_pkt);
P(jcr->mutex);
- jcr->JobFiles++; /* increment number of files sent */
+ jcr->JobFiles++; /* increment number of files sent */
pm_strcpy(jcr->last_fname, ff_pkt->fname);
V(jcr->mutex);
/*
* Send file attributes to Director
- * File_index
- * Stream
- * Verify Options
- * Filename (full path)
- * Encoded attributes
- * Link name (if type==FT_LNK)
+ * File_index
+ * Stream
+ * Verify Options
+ * Filename (full path)
+ * Encoded attributes
+ * Link name (if type==FT_LNK)
* For a directory, link is the same as fname, but with trailing
* slash. For a linked file, link is the link.
*/
Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname);
if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) {
stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles,
- STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
- 0, attribs, 0, ff_pkt->link, 0);
+ STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
+ 0, attribs, 0, ff_pkt->link, 0);
} else if (ff_pkt->type == FT_DIREND) {
- /* Here link is the canonical filename (i.e. with trailing slash) */
- stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
- STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link,
- 0, attribs, 0, 0);
+ /* Here link is the canonical filename (i.e. with trailing slash) */
+ stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
+ STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link,
+ 0, attribs, 0, 0);
} else {
stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles,
- STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
- 0, attribs, 0, 0);
+ STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname,
+ 0, attribs, 0, 0);
}
Dmsg2(20, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg);
if (!stat) {
* First we initialise, then we read files, other streams and Finder Info.
*/
if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) &&
- ff_pkt->flags & (FO_MD5|FO_SHA1))) {
+ ff_pkt->flags & (FO_MD5|FO_SHA1))) {
chksum_init(&chksum, ff_pkt->flags);
binit(&bfd);
if (ff_pkt->statp.st_size > 0 || ff_pkt->type == FT_RAW
- || ff_pkt->type == FT_FIFO) {
- if ((bopen(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0)) < 0) {
- ff_pkt->ff_errno = errno;
- berrno be;
- be.set_errno(bfd.berrno);
- Jmsg(jcr, M_NOTSAVED, 1, _(" Cannot open %s: ERR=%s.\n"),
- ff_pkt->fname, be.strerror());
- jcr->Errors++;
- return 1;
- }
- read_chksum(&bfd, &chksum, jcr);
- bclose(&bfd);
+ || ff_pkt->type == FT_FIFO) {
+ if ((bopen(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0)) < 0) {
+ ff_pkt->ff_errno = errno;
+ berrno be;
+ be.set_errno(bfd.berrno);
+ Jmsg(jcr, M_NOTSAVED, 1, _(" Cannot open %s: ERR=%s.\n"),
+ ff_pkt->fname, be.strerror());
+ jcr->Errors++;
+ return 1;
+ }
+ read_chksum(&bfd, &chksum, jcr);
+ bclose(&bfd);
}
#ifdef HAVE_DARWIN_OS
/* Open resource fork if necessary */
if (ff_pkt->flags & FO_HFSPLUS && ff_pkt->hfsinfo.rsrclength > 0) {
- if (bopen_rsrc(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
- ff_pkt->ff_errno = errno;
- berrno be;
- Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for %s: ERR=%s\n"),
- ff_pkt->fname, be.strerror());
- jcr->Errors++;
- if (is_bopen(&ff_pkt->bfd)) {
- bclose(&ff_pkt->bfd);
- }
- return 1;
- }
- read_chksum(&bfd, &chksum, jcr);
- bclose(&bfd);
+ if (bopen_rsrc(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) {
+ ff_pkt->ff_errno = errno;
+ berrno be;
+ Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open resource fork for %s: ERR=%s\n"),
+ ff_pkt->fname, be.strerror());
+ jcr->Errors++;
+ if (is_bopen(&ff_pkt->bfd)) {
+ bclose(&ff_pkt->bfd);
+ }
+ return 1;
+ }
+ read_chksum(&bfd, &chksum, jcr);
+ bclose(&bfd);
}
if (ff_pkt->flags & FO_HFSPLUS) {
- chksum_update(&chksum, ((unsigned char *)ff_pkt->hfsinfo.fndrinfo), 32);
+ chksum_update(&chksum, ((unsigned char *)ff_pkt->hfsinfo.fndrinfo), 32);
}
#endif
/* compute MD5 or SHA1 hash */
if (chksum.updated) {
- char chksumbuf[40]; /* 24 should do */
- int stream = 0;
+ char chksumbuf[40]; /* 24 should do */
+ int stream = 0;
- chksum_final(&chksum);
- if (chksum.type == CHKSUM_MD5) {
- stream = STREAM_MD5_SIGNATURE;
- } else if (chksum.type == CHKSUM_SHA1) {
- stream = STREAM_SHA1_SIGNATURE;
- }
- bin_to_base64(chksumbuf, (char *)chksum.signature, chksum.length);
- Dmsg3(400, "send inx=%d %s=%s\n", jcr->JobFiles, chksum.name, chksumbuf);
- bnet_fsend(dir, "%d %d %s *%s-%d*", jcr->JobFiles, stream, chksumbuf,
- chksum.name, jcr->JobFiles);
- Dmsg3(20, "bfiled>bdird: %s len=%d: msg=%s\n", chksum.name,
- dir->msglen, dir->msg);
+ chksum_final(&chksum);
+ if (chksum.type == CHKSUM_MD5) {
+ stream = STREAM_MD5_SIGNATURE;
+ } else if (chksum.type == CHKSUM_SHA1) {
+ stream = STREAM_SHA1_SIGNATURE;
+ }
+ bin_to_base64(chksumbuf, (char *)chksum.signature, chksum.length);
+ Dmsg3(400, "send inx=%d %s=%s\n", jcr->JobFiles, chksum.name, chksumbuf);
+ bnet_fsend(dir, "%d %d %s *%s-%d*", jcr->JobFiles, stream, chksumbuf,
+ chksum.name, jcr->JobFiles);
+ Dmsg3(20, "bfiled>bdird: %s len=%d: msg=%s\n", chksum.name,
+ dir->msglen, dir->msg);
}
}
berrno be;
be.set_errno(bfd->berrno);
Jmsg(jcr, M_ERROR, 1, _("Error reading file %s: ERR=%s\n"),
- jcr->last_fname, be.strerror());
+ jcr->last_fname, be.strerror());
jcr->Errors++;
return -1;
}
/* ===============================================================
*
- * U N I X AND W I N D O W S
+ * U N I X AND W I N D O W S
*
* ===============================================================
*/
/* ===============================================================
*
- * W I N D O W S
+ * W I N D O W S
*
* ===============================================================
*/
/*
* Return 1 if we support the stream
- * 0 if we do not support the stream
+ * 0 if we do not support the stream
*/
int is_stream_supported(int stream)
{
case STREAM_MACOS_FORK_DATA:
case STREAM_HFSPLUS_ATTRIBUTES:
#endif
- case 0: /* compatibility with old tapes */
+ case 0: /* compatibility with old tapes */
return 1;
}
return 0;
win32_fname = get_pool_memory(PM_FNAME);
unix_name_to_win32(&win32_fname, (char *)fname);
- if (flags & O_CREAT) { /* Create */
+ if (flags & O_CREAT) { /* Create */
if (bfd->use_backup_api) {
- dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
- dwflags = FILE_FLAG_BACKUP_SEMANTICS;
+ dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
+ dwflags = FILE_FLAG_BACKUP_SEMANTICS;
} else {
- dwaccess = GENERIC_WRITE;
- dwflags = 0;
+ dwaccess = GENERIC_WRITE;
+ dwflags = 0;
}
bfd->fh = CreateFile(win32_fname,
- dwaccess, /* Requested access */
- 0, /* Shared mode */
- NULL, /* SecurityAttributes */
- CREATE_ALWAYS, /* CreationDisposition */
- dwflags, /* Flags and attributes */
- NULL); /* TemplateFile */
+ dwaccess, /* Requested access */
+ 0, /* Shared mode */
+ NULL, /* SecurityAttributes */
+ CREATE_ALWAYS, /* CreationDisposition */
+ dwflags, /* Flags and attributes */
+ NULL); /* TemplateFile */
bfd->mode = BF_WRITE;
} else if (flags & O_WRONLY) { /* Open existing for write */
if (bfd->use_backup_api) {
- dwaccess = GENERIC_WRITE|WRITE_OWNER|WRITE_DAC;
- dwflags = FILE_FLAG_BACKUP_SEMANTICS;
+ dwaccess = GENERIC_WRITE|WRITE_OWNER|WRITE_DAC;
+ dwflags = FILE_FLAG_BACKUP_SEMANTICS;
} else {
- dwaccess = GENERIC_WRITE;
- dwflags = 0;
+ dwaccess = GENERIC_WRITE;
+ dwflags = 0;
}
bfd->fh = CreateFile(win32_fname,
- dwaccess, /* Requested access */
- 0, /* Shared mode */
- NULL, /* SecurityAttributes */
- OPEN_EXISTING, /* CreationDisposition */
- dwflags, /* Flags and attributes */
- NULL); /* TemplateFile */
+ dwaccess, /* Requested access */
+ 0, /* Shared mode */
+ NULL, /* SecurityAttributes */
+ OPEN_EXISTING, /* CreationDisposition */
+ dwflags, /* Flags and attributes */
+ NULL); /* TemplateFile */
bfd->mode = BF_WRITE;
- } else { /* Read */
+ } else { /* Read */
if (bfd->use_backup_api) {
- dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
- dwflags = FILE_FLAG_BACKUP_SEMANTICS;
- dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
+ dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
+ dwflags = FILE_FLAG_BACKUP_SEMANTICS;
+ dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
} else {
- dwaccess = GENERIC_READ;
- dwflags = 0;
- dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE;
+ dwaccess = GENERIC_READ;
+ dwflags = 0;
+ dwshare = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
bfd->fh = CreateFile(win32_fname,
- dwaccess, /* Requested access */
- dwshare, /* Share modes */
- NULL, /* SecurityAttributes */
- OPEN_EXISTING, /* CreationDisposition */
- dwflags, /* Flags and attributes */
- NULL); /* TemplateFile */
+ dwaccess, /* Requested access */
+ dwshare, /* Share modes */
+ NULL, /* SecurityAttributes */
+ OPEN_EXISTING, /* CreationDisposition */
+ dwflags, /* Flags and attributes */
+ NULL); /* TemplateFile */
bfd->mode = BF_READ;
}
/*
* Returns 0 on success
- * -1 on error
+ * -1 on error
*/
int bclose(BFILE *bfd)
{
if (bfd->use_backup_api && bfd->mode == BF_READ) {
BYTE buf[10];
if (!bfd->lpContext && !p_BackupRead(bfd->fh,
- buf, /* buffer */
- (DWORD)0, /* bytes to read */
- &bfd->rw_bytes, /* bytes read */
- 1, /* Abort */
- 1, /* ProcessSecurity */
- &bfd->lpContext)) { /* Read context */
- errno = b_errno_win32;
- stat = -1;
+ buf, /* buffer */
+ (DWORD)0, /* bytes to read */
+ &bfd->rw_bytes, /* bytes read */
+ 1, /* Abort */
+ 1, /* ProcessSecurity */
+ &bfd->lpContext)) { /* Read context */
+ errno = b_errno_win32;
+ stat = -1;
}
} else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
BYTE buf[10];
if (!bfd->lpContext && !p_BackupWrite(bfd->fh,
- buf, /* buffer */
- (DWORD)0, /* bytes to read */
- &bfd->rw_bytes, /* bytes written */
- 1, /* Abort */
- 1, /* ProcessSecurity */
- &bfd->lpContext)) { /* Write context */
- errno = b_errno_win32;
- stat = -1;
+ buf, /* buffer */
+ (DWORD)0, /* bytes to read */
+ &bfd->rw_bytes, /* bytes written */
+ 1, /* Abort */
+ 1, /* ProcessSecurity */
+ &bfd->lpContext)) { /* Write context */
+ errno = b_errno_win32;
+ stat = -1;
}
}
if (!CloseHandle(bfd->fh)) {
}
/* Returns: bytes read on success
- * 0 on EOF
- * -1 on error
+ * 0 on EOF
+ * -1 on error
*/
ssize_t bread(BFILE *bfd, void *buf, size_t count)
{
if (bfd->use_backup_api) {
if (!p_BackupRead(bfd->fh,
- (BYTE *)buf,
- count,
- &bfd->rw_bytes,
- 0, /* no Abort */
- 1, /* Process Security */
- &bfd->lpContext)) { /* Context */
- bfd->lerror = GetLastError();
- bfd->berrno = b_errno_win32;
- errno = b_errno_win32;
- return -1;
+ (BYTE *)buf,
+ count,
+ &bfd->rw_bytes,
+ 0, /* no Abort */
+ 1, /* Process Security */
+ &bfd->lpContext)) { /* Context */
+ bfd->lerror = GetLastError();
+ bfd->berrno = b_errno_win32;
+ errno = b_errno_win32;
+ return -1;
}
} else {
if (!ReadFile(bfd->fh,
- buf,
- count,
- &bfd->rw_bytes,
- NULL)) {
- bfd->lerror = GetLastError();
- bfd->berrno = b_errno_win32;
- errno = b_errno_win32;
- return -1;
+ buf,
+ count,
+ &bfd->rw_bytes,
+ NULL)) {
+ bfd->lerror = GetLastError();
+ bfd->berrno = b_errno_win32;
+ errno = b_errno_win32;
+ return -1;
}
}
if (bfd->use_backup_api) {
if (!p_BackupWrite(bfd->fh,
- (BYTE *)buf,
- count,
- &bfd->rw_bytes,
- 0, /* No abort */
- 1, /* Process Security */
- &bfd->lpContext)) { /* Context */
- bfd->lerror = GetLastError();
- bfd->berrno = b_errno_win32;
- errno = b_errno_win32;
- return -1;
+ (BYTE *)buf,
+ count,
+ &bfd->rw_bytes,
+ 0, /* No abort */
+ 1, /* Process Security */
+ &bfd->lpContext)) { /* Context */
+ bfd->lerror = GetLastError();
+ bfd->berrno = b_errno_win32;
+ errno = b_errno_win32;
+ return -1;
}
} else {
if (!WriteFile(bfd->fh,
- buf,
- count,
- &bfd->rw_bytes,
- NULL)) {
- bfd->lerror = GetLastError();
- bfd->berrno = b_errno_win32;
- errno = b_errno_win32;
- return -1;
+ buf,
+ count,
+ &bfd->rw_bytes,
+ NULL)) {
+ bfd->lerror = GetLastError();
+ bfd->berrno = b_errno_win32;
+ errno = b_errno_win32;
+ return -1;
}
}
return (ssize_t)bfd->rw_bytes;
/* ===============================================================
*
- * U N I X
+ * U N I X
*
* ===============================================================
*/
int have_win32_api()
{
- return 0; /* no can do */
+ return 0; /* no can do */
}
/*
*/
int set_win32_backup(BFILE *bfd)
{
- return 0; /* no can do */
+ return 0; /* no can do */
}
int set_portable_backup(BFILE *bfd)
{
- return 1; /* no problem */
+ return 1; /* no problem */
}
/*
*/
int is_portable_backup(BFILE *bfd)
{
- return 1; /* portable by definition */
+ return 1; /* portable by definition */
}
void set_prog(BFILE *bfd, char *prog, JCR *jcr)
case STREAM_MACOS_FORK_DATA:
case STREAM_HFSPLUS_ATTRIBUTES:
#endif
- case 0: /* compatibility with old tapes */
+ case 0: /* compatibility with old tapes */
return 1;
}
int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
{
/* Open reader/writer program */
+#ifdef xxx
if (bfd->prog) {
POOLMEM *ecmd = get_pool_memory(PM_FNAME);
ecmd = edit_job_codes(bfd->jcr, ecmd, bfd->prog, fname);
const char *pmode;
if (flags & O_RDONLY) {
- pmode = "r";
+ pmode = "r";
} else {
- pmode = "w";
+ pmode = "w";
}
bfd->bpipe = open_bpipe(ecmd, 0, pmode);
if (bfd->bpipe == NULL) {
- bfd->berrno = errno;
- bfd->fid = -1;
- free_pool_memory(ecmd);
- return -1;
+ bfd->berrno = errno;
+ bfd->fid = -1;
+ free_pool_memory(ecmd);
+ return -1;
}
free_pool_memory(ecmd);
if (flags & O_RDONLY) {
- bfd->fid = fileno(bfd->bpipe->rfd);
+ bfd->fid = fileno(bfd->bpipe->rfd);
} else {
- bfd->fid = fileno(bfd->bpipe->wfd);
+ bfd->fid = fileno(bfd->bpipe->wfd);
}
errno = 0;
return bfd->fid;
}
+#endif
/* Normal file open */
bfd->fid = open(fname, flags, mode);
return 0;
}
/* Close reader/writer program */
+#ifdef xxx
if (bfd->prog && bfd->bpipe) {
stat = close_bpipe(bfd->bpipe);
bfd->berrno = errno;
bfd->bpipe = NULL;
return stat;
}
+#endif
/* Close normal file */
stat = close(bfd->fid);
#include "bacula.h"
#include "find.h"
-int32_t name_max; /* filename max length */
-int32_t path_max; /* path name max length */
+int32_t name_max; /* filename max length */
+int32_t path_max; /* path name max length */
#ifdef DEBUG
#undef bmalloc
#define bmalloc(x) sm_malloc(__FILE__, __LINE__, x)
#endif
-static int our_callback(FF_PKT *ff, void *hpkt);
+static int our_callback(FF_PKT *ff, void *hpkt, bool top_level);
static bool accept_file(FF_PKT *ff);
/* Fold case in fnmatch() on Win32 */
if (name_max < 1024) {
name_max = 1024;
}
- path_max++; /* add for EOS */
- name_max++; /* add for EOS */
+ path_max++; /* add for EOS */
+ name_max++; /* add for EOS */
Dmsg1(100, "init_find_files ff=%p\n", ff);
return ff;
*
*/
int
-find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt), void *his_pkt)
+find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt, bool top_level),
+ void *his_pkt)
{
ff->callback = callback;
ff->VerifyOpts[0] = 'V';
ff->VerifyOpts[1] = 0;
for (i=0; i<fileset->include_list.size(); i++) {
- findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
- fileset->incexe = incexe;
- /*
- * By setting all options, we in effect or the global options
- * which is what we want.
- */
- for (j=0; j<incexe->opts_list.size(); j++) {
- findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
- ff->flags |= fo->flags;
- ff->GZIP_level = fo->GZIP_level;
- ff->fstypes = fo->fstype;
- bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts));
- }
- for (j=0; j<incexe->name_list.size(); j++) {
+ findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i);
+ fileset->incexe = incexe;
+ /*
+ * By setting all options, we in effect or the global options
+ * which is what we want.
+ */
+ for (j=0; j<incexe->opts_list.size(); j++) {
+ findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+ ff->flags |= fo->flags;
+ ff->GZIP_level = fo->GZIP_level;
+ ff->fstypes = fo->fstype;
+ bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts));
+ }
+ for (j=0; j<incexe->name_list.size(); j++) {
Dmsg1(100, "F %s\n", (char *)incexe->name_list.get(j));
- char *fname = (char *)incexe->name_list.get(j);
- if (find_one_file(jcr, ff, our_callback, his_pkt, fname, (dev_t)-1, 1) == 0) {
- return 0; /* error return */
- }
- }
+ char *fname = (char *)incexe->name_list.get(j);
+ if (find_one_file(jcr, ff, our_callback, his_pkt, fname, (dev_t)-1, true) == 0) {
+ return 0; /* error return */
+ }
+ }
}
}
return 1;
ff->fstypes = fo->fstype;
ic = (ff->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
if (S_ISDIR(ff->statp.st_mode)) {
- for (k=0; k<fo->wilddir.size(); k++) {
- if (fnmatch((char *)fo->wilddir.get(k), ff->fname, fnmode|ic) == 0) {
- if (ff->flags & FO_EXCLUDE) {
+ for (k=0; k<fo->wilddir.size(); k++) {
+ if (fnmatch((char *)fo->wilddir.get(k), ff->fname, fnmode|ic) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
Dmsg2(100, "Exclude wilddir: %s file=%s\n", (char *)fo->wilddir.get(k),
- ff->fname);
- return false; /* reject file */
- }
- return true; /* accept file */
- }
- }
+ ff->fname);
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
} else {
- for (k=0; k<fo->wildfile.size(); k++) {
- if (fnmatch((char *)fo->wildfile.get(k), ff->fname, fnmode|ic) == 0) {
- if (ff->flags & FO_EXCLUDE) {
+ for (k=0; k<fo->wildfile.size(); k++) {
+ if (fnmatch((char *)fo->wildfile.get(k), ff->fname, fnmode|ic) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
Dmsg2(100, "Exclude wildfile: %s file=%s\n", (char *)fo->wildfile.get(k),
- ff->fname);
- return false; /* reject file */
- }
- return true; /* accept file */
- }
- }
+ ff->fname);
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
}
for (k=0; k<fo->wild.size(); k++) {
- if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|ic) == 0) {
- if (ff->flags & FO_EXCLUDE) {
+ if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|ic) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
Dmsg2(100, "Exclude wild: %s file=%s\n", (char *)fo->wild.get(k),
- ff->fname);
- return false; /* reject file */
- }
- return true; /* accept file */
- }
+ ff->fname);
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
}
#ifndef WIN32
if (S_ISDIR(ff->statp.st_mode)) {
- for (k=0; k<fo->regexdir.size(); k++) {
- const int nmatch = 30;
- regmatch_t pmatch[nmatch];
- if (regexec((regex_t *)fo->regexdir.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
- if (ff->flags & FO_EXCLUDE) {
- return false; /* reject file */
- }
- return true; /* accept file */
- }
- }
+ for (k=0; k<fo->regexdir.size(); k++) {
+ const int nmatch = 30;
+ regmatch_t pmatch[nmatch];
+ if (regexec((regex_t *)fo->regexdir.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
} else {
- for (k=0; k<fo->regexfile.size(); k++) {
- const int nmatch = 30;
- regmatch_t pmatch[nmatch];
- if (regexec((regex_t *)fo->regexfile.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
- if (ff->flags & FO_EXCLUDE) {
- return false; /* reject file */
- }
- return true; /* accept file */
- }
- }
+ for (k=0; k<fo->regexfile.size(); k++) {
+ const int nmatch = 30;
+ regmatch_t pmatch[nmatch];
+ if (regexec((regex_t *)fo->regexfile.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
}
for (k=0; k<fo->regex.size(); k++) {
- const int nmatch = 30;
- regmatch_t pmatch[nmatch];
- if (regexec((regex_t *)fo->regex.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
- if (ff->flags & FO_EXCLUDE) {
- return false; /* reject file */
- }
- return true; /* accept file */
- }
+ const int nmatch = 30;
+ regmatch_t pmatch[nmatch];
+ if (regexec((regex_t *)fo->regex.get(k), ff->fname, nmatch, pmatch, 0) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
}
#endif
+ /*
+ * If we have an empty Options clause with exclude, then
+ * exclude the file
+ */
+ if (ff->flags & FO_EXCLUDE &&
+ fo->regex.size() == 0 && fo->wild.size() == 0 &&
+ fo->regexdir.size() == 0 && fo->wilddir.size() == 0 &&
+ fo->regexfile.size() == 0 && fo->wildfile.size() == 0) {
+ return false; /* reject file */
+ }
}
+ /* Now apply the Exclude { } directive */
for (i=0; i<fileset->exclude_list.size(); i++) {
findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
for (j=0; j<incexe->opts_list.size(); j++) {
- findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
- ic = (fo->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
- for (k=0; k<fo->wild.size(); k++) {
- if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|ic) == 0) {
+ findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+ ic = (fo->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
+ for (k=0; k<fo->wild.size(); k++) {
+ if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|ic) == 0) {
Dmsg1(100, "Reject wild1: %s\n", ff->fname);
- return false; /* reject file */
- }
- }
+ return false; /* reject file */
+ }
+ }
}
ic = (incexe->current_opts != NULL && incexe->current_opts->flags & FO_IGNORECASE)
- ? FNM_CASEFOLD : 0;
+ ? FNM_CASEFOLD : 0;
for (j=0; j<incexe->name_list.size(); j++) {
- if (fnmatch((char *)incexe->name_list.get(j), ff->fname, fnmode|ic) == 0) {
+ if (fnmatch((char *)incexe->name_list.get(j), ff->fname, fnmode|ic) == 0) {
Dmsg1(100, "Reject wild2: %s\n", ff->fname);
- return false; /* reject file */
- }
+ return false; /* reject file */
+ }
}
}
return true;
* We filter the files, then call the user's callback if
* the file is included.
*/
-static int our_callback(FF_PKT *ff, void *hpkt)
+static int our_callback(FF_PKT *ff, void *hpkt, bool top_level)
{
+ if (top_level) {
+ return ff->callback(ff, hpkt, top_level); /* accept file */
+ }
switch (ff->type) {
case FT_NOACCESS:
case FT_NOFOLLOW:
case FT_NOFSCHG:
case FT_INVALIDFS:
case FT_NOOPEN:
-// return ff->callback(ff, hpkt);
+// return ff->callback(ff, hpkt, top_level);
/* These items can be filtered */
case FT_LNKSAVED:
case FT_SPEC:
case FT_DIRNOCHG:
if (accept_file(ff)) {
- return ff->callback(ff, hpkt);
+ return ff->callback(ff, hpkt, top_level);
} else {
Dmsg1(100, "Skip file %s\n", ff->fname);
- return -1; /* ignore this file */
+ return -1; /* ignore this file */
}
default:
* Status codes returned by create_file()
*/
enum {
- CF_SKIP = 1, /* skip file (not newer or something) */
- CF_ERROR, /* error creating file */
- CF_EXTRACT, /* file created, data to extract */
- CF_CREATED /* file created, no data to extract */
+ CF_SKIP = 1, /* skip file (not newer or something) */
+ CF_ERROR, /* error creating file */
+ CF_EXTRACT, /* file created, data to extract */
+ CF_CREATED /* file created, no data to extract */
};
/* Options saved int "options" of the include/exclude lists.
* They are directly jammed ito "flag" of ff packet
*/
-#define FO_MD5 (1<<1) /* Do MD5 checksum */
-#define FO_GZIP (1<<2) /* Do Zlib compression */
-#define FO_NO_RECURSION (1<<3) /* no recursion in directories */
-#define FO_MULTIFS (1<<4) /* multiple file systems */
-#define FO_SPARSE (1<<5) /* do sparse file checking */
-#define FO_IF_NEWER (1<<6) /* replace if newer */
-#define FO_NOREPLACE (1<<7) /* never replace */
-#define FO_READFIFO (1<<8) /* read data from fifo */
-#define FO_SHA1 (1<<9) /* Do SHA1 checksum */
-#define FO_PORTABLE (1<<10) /* Use portable data format -- no BackupWrite */
-#define FO_MTIMEONLY (1<<11) /* Use mtime rather than mtime & ctime */
-#define FO_KEEPATIME (1<<12) /* Reset access time */
-#define FO_EXCLUDE (1<<13) /* Exclude file */
-#define FO_ACL (1<<14) /* Backup ACLs */
+#define FO_MD5 (1<<1) /* Do MD5 checksum */
+#define FO_GZIP (1<<2) /* Do Zlib compression */
+#define FO_NO_RECURSION (1<<3) /* no recursion in directories */
+#define FO_MULTIFS (1<<4) /* multiple file systems */
+#define FO_SPARSE (1<<5) /* do sparse file checking */
+#define FO_IF_NEWER (1<<6) /* replace if newer */
+#define FO_NOREPLACE (1<<7) /* never replace */
+#define FO_READFIFO (1<<8) /* read data from fifo */
+#define FO_SHA1 (1<<9) /* Do SHA1 checksum */
+#define FO_PORTABLE (1<<10) /* Use portable data format -- no BackupWrite */
+#define FO_MTIMEONLY (1<<11) /* Use mtime rather than mtime & ctime */
+#define FO_KEEPATIME (1<<12) /* Reset access time */
+#define FO_EXCLUDE (1<<13) /* Exclude file */
+#define FO_ACL (1<<14) /* Backup ACLs */
#define FO_NO_HARDLINK (1<<15) /* don't handle hard links */
-#define FO_IGNORECASE (1<<16) /* Ignore file name case */
-#define FO_HFSPLUS (1<<17) /* Resource forks and Finder Info */
+#define FO_IGNORECASE (1<<16) /* Ignore file name case */
+#define FO_HFSPLUS (1<<17) /* Resource forks and Finder Info */
struct s_included_file {
struct s_included_file *next;
- uint32_t options; /* backup options */
- int level; /* compression level */
- int len; /* length of fname */
- int pattern; /* set if wild card pattern */
- char VerifyOpts[20]; /* Options for verify */
+ uint32_t options; /* backup options */
+ int level; /* compression level */
+ int len; /* length of fname */
+ int pattern; /* set if wild card pattern */
+ char VerifyOpts[20]; /* Options for verify */
char fname[1];
};
* of the structure are passed by the Director to the
* File daemon and recompiled back into this structure
*/
-#undef MAX_FOPTS
+#undef MAX_FOPTS
#define MAX_FOPTS 30
enum {
/* File options structure */
struct findFOPTS {
- uint32_t flags; /* options in bits */
- int GZIP_level; /* GZIP level */
- char VerifyOpts[MAX_FOPTS]; /* verify options */
- alist regex; /* regex string(s) */
- alist regexdir; /* regex string(s) for directories */
- alist regexfile; /* regex string(s) for files */
- alist wild; /* wild card strings */
- alist wilddir; /* wild card strings for directories */
- alist wildfile; /* wild card strings for files */
- alist base; /* list of base names */
- alist fstype; /* file system type limitation */
- char *reader; /* reader program */
- char *writer; /* writer program */
+ uint32_t flags; /* options in bits */
+ int GZIP_level; /* GZIP level */
+ char VerifyOpts[MAX_FOPTS]; /* verify options */
+ alist regex; /* regex string(s) */
+ alist regexdir; /* regex string(s) for directories */
+ alist regexfile; /* regex string(s) for files */
+ alist wild; /* wild card strings */
+ alist wilddir; /* wild card strings for directories */
+ alist wildfile; /* wild card strings for files */
+ alist base; /* list of base names */
+ alist fstype; /* file system type limitation */
+ char *reader; /* reader program */
+ char *writer; /* writer program */
};
/* This is either an include item or an exclude item */
struct findINCEXE {
- findFOPTS *current_opts; /* points to current options structure */
- alist opts_list; /* options list */
- alist name_list; /* filename list -- holds char * */
+ findFOPTS *current_opts; /* points to current options structure */
+ alist opts_list; /* options list */
+ alist name_list; /* filename list -- holds char * */
};
/*
*/
struct findFILESET {
int state;
- findINCEXE *incexe; /* current item */
+ findINCEXE *incexe; /* current item */
alist include_list;
alist exclude_list;
};
#ifdef HAVE_DARWIN_OS
struct HFSPLUS_INFO {
- unsigned long length; /* Mandatory field */
- char fndrinfo[32]; /* Finder Info */
- off_t rsrclength; /* Size of resource fork */
+ unsigned long length; /* Mandatory field */
+ char fndrinfo[32]; /* Finder Info */
+ off_t rsrclength; /* Size of resource fork */
};
#endif
* first argument to the find_files callback subroutine.
*/
struct FF_PKT {
- char *fname; /* filename */
- char *link; /* link if file linked */
- POOLMEM *sys_fname; /* system filename */
- struct stat statp; /* stat packet */
- int32_t FileIndex; /* FileIndex of this file */
- int32_t LinkFI; /* FileIndex of main hard linked file */
- struct f_link *linked; /* Set if this file is hard linked */
- int type; /* FT_ type from above */
- int ff_errno; /* errno */
- BFILE bfd; /* Bacula file descriptor */
- time_t save_time; /* start of incremental time */
- bool dereference; /* follow links (not implemented) */
- bool null_output_device; /* using null output device */
- bool incremental; /* incremental save */
+ char *fname; /* filename */
+ char *link; /* link if file linked */
+ POOLMEM *sys_fname; /* system filename */
+ struct stat statp; /* stat packet */
+ int32_t FileIndex; /* FileIndex of this file */
+ int32_t LinkFI; /* FileIndex of main hard linked file */
+ struct f_link *linked; /* Set if this file is hard linked */
+ int type; /* FT_ type from above */
+ int ff_errno; /* errno */
+ BFILE bfd; /* Bacula file descriptor */
+ time_t save_time; /* start of incremental time */
+ bool dereference; /* follow links (not implemented) */
+ bool null_output_device; /* using null output device */
+ bool incremental; /* incremental save */
char VerifyOpts[20];
struct s_included_file *included_files_list;
struct s_excluded_file *excluded_files_list;
struct s_excluded_file *excluded_paths_list;
findFILESET *fileset;
- int (*callback)(FF_PKT *, void *); /* User's callback */
+ int (*callback)(FF_PKT *, void *, bool); /* User's callback */
/* Values set by accept_file while processing Options */
- uint32_t flags; /* backup options */
- int GZIP_level; /* compression level */
- char *reader; /* reader program */
- char *writer; /* writer program */
- alist fstypes; /* allowed file system types */
+ uint32_t flags; /* backup options */
+ int GZIP_level; /* compression level */
+ char *reader; /* reader program */
+ char *writer; /* writer program */
+ alist fstypes; /* allowed file system types */
/* List of all hard linked files found */
- struct f_link *linklist; /* hard linked files */
+ struct f_link *linklist; /* hard linked files */
/* Darwin specific things.
* To avoid clutter, we always include rsrc_bfd and volhas_attrlist */
- BFILE rsrc_bfd; /* fd for resource forks */
- bool volhas_attrlist; /* Volume supports getattrlist() */
+ BFILE rsrc_bfd; /* fd for resource forks */
+ bool volhas_attrlist; /* Volume supports getattrlist() */
#ifdef HAVE_DARWIN_OS
struct HFSPLUS_INFO hfsinfo; /* Finder Info and resource fork size */
#endif
#include <sys/attr.h>
#endif
-extern int32_t name_max; /* filename max length */
-extern int32_t path_max; /* path name max length */
+extern int32_t name_max; /* filename max length */
+extern int32_t path_max; /* path name max length */
/*
* Structure for keeping track of hard linked files, we
*/
struct f_link {
struct f_link *next;
- dev_t dev; /* device */
- ino_t ino; /* inode with device is unique */
+ dev_t dev; /* device */
+ ino_t ino; /* inode with device is unique */
short linkcount;
- uint32_t FileIndex; /* Bacula FileIndex of this file */
- char name[1]; /* The name */
+ uint32_t FileIndex; /* Bacula FileIndex of this file */
+ char name[1]; /* The name */
};
static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt)
if (!fstype(ff->fname, fs, sizeof(fs))) {
Dmsg1(50, "Cannot determine file system type for \"%s\"\n", ff->fname);
} else {
- for (i = 0; i < ff->fstypes.size(); ++i) {
- if (strcmp(fs, (char *)ff->fstypes.get(i)) == 0) {
+ for (i = 0; i < ff->fstypes.size(); ++i) {
+ if (strcmp(fs, (char *)ff->fstypes.get(i)) == 0) {
Dmsg2(100, "Accepting fstype %s for \"%s\"\n", fs, ff->fname);
- accept = true;
- break;
- }
+ accept = true;
+ break;
+ }
Dmsg3(200, "fstype %s for \"%s\" does not match %s\n", fs,
- ff->fname, ff->fstypes.get(i));
- }
+ ff->fname, ff->fstypes.get(i));
+ }
}
}
return accept;
#ifdef HAVE_DARWIN_OS
struct statfs st;
struct volinfo_struct {
- unsigned long length; /* Mandatory field */
- vol_capabilities_attr_t info; /* Volume capabilities */
+ unsigned long length; /* Mandatory field */
+ vol_capabilities_attr_t info; /* Volume capabilities */
} vol;
struct attrlist attrList;
if (statfs(fname, &st) == 0) {
/* We need to check on the mount point */
if (getattrlist(st.f_mntonname, &attrList, &vol, sizeof(vol), FSOPT_NOFOLLOW) == 0
- && (vol.info.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_ATTRLIST)
- && (vol.info.valid[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_ATTRLIST)) {
- return true;
+ && (vol.info.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_ATTRLIST)
+ && (vol.info.valid[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_ATTRLIST)) {
+ return true;
}
}
#endif
* descending into a directory.
*/
int
-find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
- void *pkt, char *fname, dev_t parent_device, int top_level)
+find_one_file(JCR *jcr, FF_PKT *ff_pkt,
+ int handle_file(FF_PKT *ff, void *hpkt, bool top_level),
+ void *pkt, char *fname, dev_t parent_device, bool top_level)
{
struct utimbuf restore_times;
int rtn_stat;
/* Cannot stat file */
ff_pkt->type = FT_NOSTAT;
ff_pkt->ff_errno = errno;
- return handle_file(ff_pkt, pkt);
+ return handle_file(ff_pkt, pkt, top_level);
}
Dmsg1(300, "File ----: %s\n", fname);
*/
if (top_level) {
if (!accept_fstype(ff_pkt, NULL)) {
- ff_pkt->type = FT_INVALIDFS;
- if (ff_pkt->flags & FO_KEEPATIME) {
- utime(fname, &restore_times);
- }
+ ff_pkt->type = FT_INVALIDFS;
+ if (ff_pkt->flags & FO_KEEPATIME) {
+ utime(fname, &restore_times);
+ }
Jmsg1(jcr, M_ERROR, 0, _("Top level directory \"%s\" has an unlisted fstype\n"), fname);
- return 1; /* Just ignore this error - or the whole backup is cancelled */
+ return 1; /* Just ignore this error - or the whole backup is cancelled */
}
ff_pkt->volhas_attrlist = volume_has_attrlist(fname);
}
Dmsg1(300, "Non-directory incremental: %s\n", ff_pkt->fname);
/* Not a directory */
if (ff_pkt->statp.st_mtime < ff_pkt->save_time
- && ((ff_pkt->flags & FO_MTIMEONLY) ||
- ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
- /* Incremental option, file not changed */
- ff_pkt->type = FT_NOCHG;
- return handle_file(ff_pkt, pkt);
+ && ((ff_pkt->flags & FO_MTIMEONLY) ||
+ ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
+ /* Incremental option, file not changed */
+ ff_pkt->type = FT_NOCHG;
+ return handle_file(ff_pkt, pkt, top_level);
}
}
#ifdef HAVE_DARWIN_OS
if (ff_pkt->flags & FO_HFSPLUS && ff_pkt->volhas_attrlist
- && S_ISREG(ff_pkt->statp.st_mode)) {
+ && S_ISREG(ff_pkt->statp.st_mode)) {
/* TODO: initialise attrList once elsewhere? */
struct attrlist attrList;
memset(&attrList, 0, sizeof(attrList));
attrList.commonattr = ATTR_CMN_FNDRINFO;
attrList.fileattr = ATTR_FILE_RSRCLENGTH;
if (getattrlist(fname, &attrList, &ff_pkt->hfsinfo,
- sizeof(ff_pkt->hfsinfo), FSOPT_NOFOLLOW) != 0) {
- ff_pkt->type = FT_NOSTAT;
- ff_pkt->ff_errno = errno;
- return handle_file(ff_pkt, pkt);
+ sizeof(ff_pkt->hfsinfo), FSOPT_NOFOLLOW) != 0) {
+ ff_pkt->type = FT_NOSTAT;
+ ff_pkt->ff_errno = errno;
+ return handle_file(ff_pkt, pkt, top_level);
}
}
#endif
/* See if we are trying to dump the archive. */
if (ar_dev && ff_pkt->statp.st_dev == ar_dev && ff_pkt->statp.st_ino == ar_ino) {
ff_pkt->type = FT_ISARCH;
- return handle_file(ff_pkt, pkt);
+ return handle_file(ff_pkt, pkt, top_level);
}
#endif
ff_pkt->LinkFI = 0;
if (!(ff_pkt->flags & FO_NO_HARDLINK)
&& ff_pkt->statp.st_nlink > 1
&& (S_ISREG(ff_pkt->statp.st_mode)
- || S_ISCHR(ff_pkt->statp.st_mode)
- || S_ISBLK(ff_pkt->statp.st_mode)
- || S_ISFIFO(ff_pkt->statp.st_mode)
- || S_ISSOCK(ff_pkt->statp.st_mode))) {
+ || S_ISCHR(ff_pkt->statp.st_mode)
+ || S_ISBLK(ff_pkt->statp.st_mode)
+ || S_ISFIFO(ff_pkt->statp.st_mode)
+ || S_ISSOCK(ff_pkt->statp.st_mode))) {
struct f_link *lp;
/* Search link list of hard linked files */
for (lp = ff_pkt->linklist; lp; lp = lp->next)
- if (lp->ino == (ino_t)ff_pkt->statp.st_ino &&
- lp->dev == (dev_t)ff_pkt->statp.st_dev) {
+ if (lp->ino == (ino_t)ff_pkt->statp.st_ino &&
+ lp->dev == (dev_t)ff_pkt->statp.st_dev) {
/* If we have already backed up the hard linked file don't do it again */
- if (strcmp(lp->name, fname) == 0) {
+ if (strcmp(lp->name, fname) == 0) {
Jmsg1(jcr, M_WARNING, 0, _("Attempt to backup hard linked file %s twice ignored.\n"),
- fname);
- return 1; /* ignore */
- }
- ff_pkt->link = lp->name;
- ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */
- ff_pkt->LinkFI = lp->FileIndex;
- return handle_file(ff_pkt, pkt);
- }
+ fname);
+ return 1; /* ignore */
+ }
+ ff_pkt->link = lp->name;
+ ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */
+ ff_pkt->LinkFI = lp->FileIndex;
+ return handle_file(ff_pkt, pkt, top_level);
+ }
/* File not previously dumped. Chain it into our list. */
len = strlen(fname) + 1;
bstrncpy(lp->name, fname, len);
lp->next = ff_pkt->linklist;
ff_pkt->linklist = lp;
- ff_pkt->linked = lp; /* mark saved link */
+ ff_pkt->linked = lp; /* mark saved link */
} else {
ff_pkt->linked = NULL;
}
sizeleft = ff_pkt->statp.st_size;
/* Don't bother opening empty, world readable files. Also do not open
- files when archive is meant for /dev/null. */
+ files when archive is meant for /dev/null. */
if (ff_pkt->null_output_device || (sizeleft == 0
- && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) {
- ff_pkt->type = FT_REGE;
+ && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) {
+ ff_pkt->type = FT_REGE;
} else {
- ff_pkt->type = FT_REG;
+ ff_pkt->type = FT_REG;
}
- rtn_stat = handle_file(ff_pkt, pkt);
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
}
return rtn_stat;
size = readlink(fname, buffer, path_max + name_max + 101);
if (size < 0) {
- /* Could not follow link */
- ff_pkt->type = FT_NOFOLLOW;
- ff_pkt->ff_errno = errno;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- return rtn_stat;
+ /* Could not follow link */
+ ff_pkt->type = FT_NOFOLLOW;
+ ff_pkt->ff_errno = errno;
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ return rtn_stat;
}
buffer[size] = 0;
- ff_pkt->link = buffer; /* point to link */
- ff_pkt->type = FT_LNK; /* got a real link */
- rtn_stat = handle_file(ff_pkt, pkt);
+ ff_pkt->link = buffer; /* point to link */
+ ff_pkt->type = FT_LNK; /* got a real link */
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
}
return rtn_stat;
int status;
dev_t our_device = ff_pkt->statp.st_dev;
bool recurse = true;
- bool volhas_attrlist = ff_pkt->volhas_attrlist; /* Remember this if we recurse */
+ bool volhas_attrlist = ff_pkt->volhas_attrlist; /* Remember this if we recurse */
/*
* If we are using Win32 (non-portable) backup API, don't check
* in principle, we should be able to access everything.
*/
if (!have_win32_api() || (ff_pkt->flags & FO_PORTABLE)) {
- if (access(fname, R_OK) == -1 && geteuid() != 0) {
- /* Could not access() directory */
- ff_pkt->type = FT_NOACCESS;
- ff_pkt->ff_errno = errno;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- return rtn_stat;
- }
+ if (access(fname, R_OK) == -1 && geteuid() != 0) {
+ /* Could not access() directory */
+ ff_pkt->type = FT_NOACCESS;
+ ff_pkt->ff_errno = errno;
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ return rtn_stat;
+ }
}
/* Build a canonical directory name with a trailing slash in link var */
bstrncpy(link, fname, link_len);
/* Strip all trailing slashes */
while (len >= 1 && link[len - 1] == '/')
- len--;
+ len--;
link[len++] = '/'; /* add back one */
link[len] = 0;
ff_pkt->link = link;
if (ff_pkt->incremental &&
- (ff_pkt->statp.st_mtime < ff_pkt->save_time &&
- ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
- /* Incremental option, directory entry not changed */
- ff_pkt->type = FT_DIRNOCHG;
+ (ff_pkt->statp.st_mtime < ff_pkt->save_time &&
+ ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
+ /* Incremental option, directory entry not changed */
+ ff_pkt->type = FT_DIRNOCHG;
} else {
- ff_pkt->type = FT_DIRBEGIN;
+ ff_pkt->type = FT_DIRBEGIN;
}
/*
* Note, we return the directory to the calling program (handle_file)
* do not immediately save it, but do so only after everything
* in the directory is seen (i.e. the FT_DIREND).
*/
- rtn_stat = handle_file(ff_pkt, pkt);
- if (rtn_stat < 1) { /* ignore or error status */
- free(link);
- return rtn_stat;
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
+ if (rtn_stat < 1) { /* ignore or error status */
+ free(link);
+ return rtn_stat;
}
/* Done with DIRBEGIN, next call will be DIREND */
if (ff_pkt->type == FT_DIRBEGIN) {
- ff_pkt->type = FT_DIREND;
+ ff_pkt->type = FT_DIREND;
}
/*
* file systems.
*/
if (ff_pkt->flags & FO_NO_RECURSION) {
- ff_pkt->type = FT_NORECURSE;
- recurse = false;
+ ff_pkt->type = FT_NORECURSE;
+ recurse = false;
} else if (!top_level && parent_device != ff_pkt->statp.st_dev) {
- if(!(ff_pkt->flags & FO_MULTIFS)) {
- ff_pkt->type = FT_NOFSCHG;
- recurse = false;
- } else if (!accept_fstype(ff_pkt, NULL)) {
- ff_pkt->type = FT_INVALIDFS;
- recurse = false;
- } else {
- ff_pkt->volhas_attrlist = volume_has_attrlist(fname);
- }
+ if(!(ff_pkt->flags & FO_MULTIFS)) {
+ ff_pkt->type = FT_NOFSCHG;
+ recurse = false;
+ } else if (!accept_fstype(ff_pkt, NULL)) {
+ ff_pkt->type = FT_INVALIDFS;
+ recurse = false;
+ } else {
+ ff_pkt->volhas_attrlist = volume_has_attrlist(fname);
+ }
}
/* If not recursing, just backup dir and return */
if (!recurse) {
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- free(link);
- free_dir_ff_pkt(dir_ff_pkt);
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
ff_pkt->link = ff_pkt->fname; /* reset "link" */
- if (ff_pkt->flags & FO_KEEPATIME) {
- utime(fname, &restore_times);
- }
- return rtn_stat;
+ if (ff_pkt->flags & FO_KEEPATIME) {
+ utime(fname, &restore_times);
+ }
+ return rtn_stat;
}
ff_pkt->link = ff_pkt->fname; /* reset "link" */
*/
errno = 0;
if ((directory = opendir(fname)) == NULL) {
- ff_pkt->type = FT_NOOPEN;
- ff_pkt->ff_errno = errno;
- rtn_stat = handle_file(ff_pkt, pkt);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- free(link);
- free_dir_ff_pkt(dir_ff_pkt);
- return rtn_stat;
+ ff_pkt->type = FT_NOOPEN;
+ ff_pkt->ff_errno = errno;
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
+ return rtn_stat;
}
/*
rtn_stat = 1;
entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
for ( ; !job_canceled(jcr); ) {
- char *p, *q;
- int i;
+ char *p, *q;
+ int i;
- status = readdir_r(directory, entry, &result);
- if (status != 0 || result == NULL) {
+ status = readdir_r(directory, entry, &result);
+ if (status != 0 || result == NULL) {
// Dmsg2(99, "readdir returned stat=%d result=0x%x\n",
-// status, (long)result);
- break;
- }
- ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
- p = entry->d_name;
+// status, (long)result);
+ break;
+ }
+ ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry));
+ p = entry->d_name;
/* Skip `.', `..', and excluded file names. */
if (p[0] == '\0' || (p[0] == '.' && (p[1] == '\0' ||
(p[1] == '.' && p[2] == '\0')))) {
- continue;
- }
-
- if ((int)NAMELEN(entry) + len >= link_len) {
- link_len = len + NAMELEN(entry) + 1;
- link = (char *)brealloc(link, link_len + 1);
- }
- q = link + len;
- for (i=0; i < (int)NAMELEN(entry); i++) {
- *q++ = *p++;
- }
- *q = 0;
- if (!file_is_excluded(ff_pkt, link)) {
- rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0);
- if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
- }
- }
+ continue;
+ }
+
+ if ((int)NAMELEN(entry) + len >= link_len) {
+ link_len = len + NAMELEN(entry) + 1;
+ link = (char *)brealloc(link, link_len + 1);
+ }
+ q = link + len;
+ for (i=0; i < (int)NAMELEN(entry); i++) {
+ *q++ = *p++;
+ }
+ *q = 0;
+ if (!file_is_excluded(ff_pkt, link)) {
+ rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, false);
+ if (ff_pkt->linked) {
+ ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
+ }
+ }
}
closedir(directory);
free(link);
* the directory modes and dates. Temp directory values
* were used without this record.
*/
- handle_file(dir_ff_pkt, pkt); /* handle directory entry */
+ handle_file(dir_ff_pkt, pkt, top_level); /* handle directory entry */
if (ff_pkt->linked) {
- ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex;
+ ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex;
}
free_dir_ff_pkt(dir_ff_pkt);
if (ff_pkt->flags & FO_KEEPATIME) {
- utime(fname, &restore_times);
+ utime(fname, &restore_times);
}
ff_pkt->volhas_attrlist = volhas_attrlist; /* Restore value in case it changed. */
return rtn_stat;
#ifdef HAVE_FREEBSD_OS
/*
* On FreeBSD, all block devices are character devices, so
- * to be able to read a raw disk, we need the check for
- * a character device.
+ * to be able to read a raw disk, we need the check for
+ * a character device.
   * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/ad0s3
   * crw-r----- 1 root operator - 116, 0x00040002 Jun 9 19:32 /dev/rad0s3
*/
#else
if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) {
#endif
- ff_pkt->type = FT_RAW; /* raw partition */
+ ff_pkt->type = FT_RAW; /* raw partition */
} else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) &&
- ff_pkt->flags & FO_READFIFO) {
+ ff_pkt->flags & FO_READFIFO) {
ff_pkt->type = FT_FIFO;
} else {
/* The only remaining types are special (character, ...) files */
ff_pkt->type = FT_SPEC;
}
- rtn_stat = handle_file(ff_pkt, pkt);
+ rtn_stat = handle_file(ff_pkt, pkt, top_level);
if (ff_pkt->linked) {
ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
}
lc = lp;
lp = lp->next;
if (lc) {
- free(lc);
- count++;
+ free(lc);
+ count++;
}
}
ff->linklist = NULL;
/*
+ * Old style
+ *
* Routines used to keep and match include and exclude
* filename/pathname patterns.
*
* Note, this file is used for the old style include and
* excludes, so is deprecated. The new style code is
- * found in find.c.
+ * found in find.c.
* This code is still used for lists in testls and bextract.
*
* Kern E. Sibbald, December MMI
extern const int win32_client;
int
-match_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt), void *his_pkt)
+match_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt, bool), void *his_pkt)
{
ff->callback = callback;
bstrncat(ff->VerifyOpts, inc->VerifyOpts, sizeof(ff->VerifyOpts));
Dmsg1(100, "find_files: file=%s\n", inc->fname);
if (!file_is_excluded(ff, inc->fname)) {
- if (find_one_file(jcr, ff, callback, his_pkt, inc->fname, (dev_t)-1, 1) ==0) {
- return 0; /* error return */
- }
+ if (find_one_file(jcr, ff, callback, his_pkt, inc->fname, (dev_t)-1, 1) ==0) {
+ return 0; /* error return */
+ }
}
}
return 1;
/* prefixed = preceded with options */
if (prefixed) {
for (rp=fname; *rp && *rp != ' '; rp++) {
- switch (*rp) {
+ switch (*rp) {
case 'a': /* alway replace */
case '0': /* no option */
- break;
+ break;
case 'f':
- inc->options |= FO_MULTIFS;
- break;
+ inc->options |= FO_MULTIFS;
+ break;
case 'h': /* no recursion */
- inc->options |= FO_NO_RECURSION;
- break;
+ inc->options |= FO_NO_RECURSION;
+ break;
case 'M': /* MD5 */
- inc->options |= FO_MD5;
- break;
+ inc->options |= FO_MD5;
+ break;
case 'n':
- inc->options |= FO_NOREPLACE;
- break;
+ inc->options |= FO_NOREPLACE;
+ break;
case 'p': /* use portable data format */
- inc->options |= FO_PORTABLE;
- break;
+ inc->options |= FO_PORTABLE;
+ break;
case 'r': /* read fifo */
- inc->options |= FO_READFIFO;
- break;
+ inc->options |= FO_READFIFO;
+ break;
case 'S':
- inc->options |= FO_SHA1;
- break;
+ inc->options |= FO_SHA1;
+ break;
case 's':
- inc->options |= FO_SPARSE;
- break;
+ inc->options |= FO_SPARSE;
+ break;
case 'm':
- inc->options |= FO_MTIMEONLY;
- break;
+ inc->options |= FO_MTIMEONLY;
+ break;
case 'k':
- inc->options |= FO_KEEPATIME;
- break;
+ inc->options |= FO_KEEPATIME;
+ break;
case 'V': /* verify options */
- /* Copy Verify Options */
+ /* Copy Verify Options */
for (j=0; *rp && *rp != ':'; rp++) {
- inc->VerifyOpts[j] = *rp;
- if (j < (int)sizeof(inc->VerifyOpts) - 1) {
- j++;
- }
- }
- inc->VerifyOpts[j] = 0;
- break;
+ inc->VerifyOpts[j] = *rp;
+ if (j < (int)sizeof(inc->VerifyOpts) - 1) {
+ j++;
+ }
+ }
+ inc->VerifyOpts[j] = 0;
+ break;
case 'w':
- inc->options |= FO_IF_NEWER;
- break;
+ inc->options |= FO_IF_NEWER;
+ break;
case 'A':
- inc->options |= FO_ACL;
- break;
+ inc->options |= FO_ACL;
+ break;
case 'Z': /* gzip compression */
- inc->options |= FO_GZIP;
+ inc->options |= FO_GZIP;
inc->level = *++rp - '0';
Dmsg1(200, "Compression level=%d\n", inc->level);
- break;
- default:
+ break;
+ default:
Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *rp);
- break;
- }
+ break;
+ }
}
/* Skip past space(s) */
for ( ; *rp == ' '; rp++)
- {}
+ {}
} else {
rp = fname;
}
inc->pattern = 0;
for (p=inc->fname; *p; p++) {
if (*p == '*' || *p == '[' || *p == '?') {
- inc->pattern = 1;
- break;
+ inc->pattern = 1;
+ break;
}
}
#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
struct s_included_file *next;
/* Walk to end of list */
for (next=ff->included_files_list; next->next; next=next->next)
- { }
+ { }
next->next = inc;
}
Dmsg1(50, "add_fname_to_include fname=%s\n", inc->fname);
for ( ; inc; inc=inc->next ) {
if (inc->pattern) {
- if (fnmatch(inc->fname, file, fnmode|FNM_LEADING_DIR) == 0) {
- return 1;
- }
- continue;
+ if (fnmatch(inc->fname, file, fnmode|FNM_LEADING_DIR) == 0) {
+ return 1;
+ }
+ continue;
}
/*
* No wild cards. We accept a match to the
Dmsg2(900, "pat=%s file=%s\n", inc->fname, file);
len = strlen(file);
if (inc->len == len && strcmp(inc->fname, file) == 0) {
- return 1;
+ return 1;
}
if (inc->len < len && file[inc->len] == '/' &&
- strncmp(inc->fname, file, inc->len) == 0) {
- return 1;
+ strncmp(inc->fname, file, inc->len) == 0) {
+ return 1;
}
if (inc->len == 1 && inc->fname[0] == '/') {
- return 1;
+ return 1;
}
}
return 0;
for ( ; exc; exc=exc->next ) {
if (fnmatch(exc->fname, file, fnmode|FNM_PATHNAME) == 0) {
Dmsg2(900, "Match exc pat=%s: file=%s:\n", exc->fname, file);
- return 1;
+ return 1;
}
Dmsg2(900, "No match exc pat=%s: file=%s:\n", exc->fname, file);
}
for (p = file; *p; p++) {
/* Match from the beginning of a component only */
if ((p == file || (*p != '/' && *(p-1) == '/'))
- && file_in_excluded_list(ff->excluded_files_list, p)) {
- return 1;
+ && file_in_excluded_list(ff->excluded_files_list, p)) {
+ return 1;
}
}
return 0;
/* From find.c */
FF_PKT *init_find_files();
void set_find_options(FF_PKT *ff, int incremental, time_t mtime);
-int find_files(JCR *jcr, FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt), void *pkt);
-int match_files(JCR *jcr, FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt), void *pkt);
+int find_files(JCR *jcr, FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt, bool), void *pkt);
+int match_files(JCR *jcr, FF_PKT *ff, int sub(FF_PKT *ff_pkt, void *hpkt, bool), void *pkt);
int term_find_files(FF_PKT *ff);
/* From match.c */
struct s_included_file *inc);
/* From find_one.c */
-int find_one_file(JCR *jcr, FF_PKT *ff, int handle_file(FF_PKT *ff_pkt, void *hpkt),
- void *pkt, char *p, dev_t parent_device, int top_level);
+int find_one_file(JCR *jcr, FF_PKT *ff,
+ int handle_file(FF_PKT *ff_pkt, void *hpkt, bool top_level),
+ void *pkt, char *p, dev_t parent_device, bool top_level);
int term_find_one(FF_PKT *ff);
/* Pull in Bacula entry points */
extern PyMethodDef BaculaMethods[];
+typedef struct bJCRObject {
+ PyObject_HEAD
+ JCR *jcr;
+} bJCRObject;
+
+static PyTypeObject JCRType = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "bacula.jcr", /*tp_name*/
+ sizeof(bJCRObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ "JCR objects", /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+JCR *get_jcr_from_PyObject(PyObject *self)
+{
+ return ((bJCRObject *)self)->jcr;
+}
/* Start the interpreter */
void init_python_interpreter(const char *progname, const char *scripts)
bsnprintf(buf, sizeof(buf), "import sys\n"
"sys.path.append('%s')\n", scripts);
PyRun_SimpleString(buf);
+ JCRType.tp_methods = BaculaMethods;
+ PyType_Ready(&JCRType);
PyEval_ReleaseLock();
generate_event = _generate_event;
}
* module and running it.
*
* Returns: 0 if Python not configured or module not found
- * -1 on Python error
- * 1 OK
+ * -1 on Python error
+ * 1 OK
*/
int _generate_event(JCR *jcr, const char *event)
{
PyObject *pName, *pModule, *pDict, *pFunc;
- PyObject *pArgs, *pValue;
+ PyObject *pArgs, *pJCR, *pCall;
Dmsg1(100, "Generate event %s\n", event);
pName = PyString_FromString(event);
if (!pName) {
Jmsg(jcr, M_ERROR, 0, "Could not convert \"%s\" to Python string.\n", event);
- return -1; /* Could not convert string */
+ return -1; /* Could not convert string */
}
pModule = PyImport_Import(pName);
- Py_DECREF(pName); /* release pName */
+ Py_DECREF(pName); /* release pName */
if (pModule != NULL) {
pDict = PyModule_GetDict(pModule);
/* pFun: Borrowed reference */
if (pFunc && PyCallable_Check(pFunc)) {
- /* Create JCR argument to send to function */
- pArgs = PyTuple_New(1);
- pValue = PyCObject_FromVoidPtr((void *)jcr, NULL);
- if (!pValue) {
- Py_DECREF(pArgs);
- Py_DECREF(pModule);
- Jmsg(jcr, M_ERROR, 0, "Could not convert JCR to Python CObject.\n");
- return -1; /* Could not convert JCR to CObject */
- }
- /* pValue reference stolen here: */
- PyTuple_SetItem(pArgs, 0, pValue);
-
- /* Finally, we call the module here */
- pValue = PyObject_CallObject(pFunc, pArgs);
- Py_DECREF(pArgs);
- if (pValue != NULL) {
- Py_DECREF(pValue);
- } else {
- Py_DECREF(pModule);
- PyErr_Print();
+ /* Create JCR argument to send to function */
+ pArgs = PyTuple_New(1);
+ pJCR = (PyObject *)PyObject_New(bJCRObject, &JCRType);
+ ((bJCRObject *)pJCR)->jcr = jcr;
+// pValue = PyCObject_FromVoidPtr((void *)jcr, NULL);
+ if (!pJCR) {
+ Py_DECREF(pArgs);
+ Py_DECREF(pModule);
+ Jmsg(jcr, M_ERROR, 0, "Could not create JCR Python Object.\n");
+ return -1;
+ }
+ Py_INCREF(pJCR);
+ /* pJCR reference stolen here: */
+ PyTuple_SetItem(pArgs, 0, pJCR);
+
+ /* Finally, we call the module here */
+ pCall = PyObject_CallObject(pFunc, pArgs);
+ Py_DECREF(pArgs);
+ Py_DECREF(pJCR);
+ if (pCall != NULL) {
+ Py_DECREF(pCall);
+ } else {
+ Py_DECREF(pModule);
+ PyErr_Print();
Jmsg(jcr, M_ERROR, 0, "Error running Python module: %s\n", event);
- return 0; /* error running function */
- }
- /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
+ return 0; /* error running function */
+ }
+ /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
} else {
- if (PyErr_Occurred()) {
- PyErr_Print();
- }
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ }
Jmsg(jcr, M_ERROR, 0, "Python function \"%s\" not found in module.\n", event);
- return -1; /* function not found */
+ return -1; /* function not found */
}
Py_DECREF(pModule);
} else {
- return 0; /* Module not present */
+ return 0; /* Module not present */
}
Dmsg0(100, "Generate event OK\n");
return 1;
static JCR *jcr;
-static int print_file(FF_PKT *ff, void *pkt);
+static int print_file(FF_PKT *ff, void *pkt, bool);
static void count_files(FF_PKT *ff);
static void usage()
while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
switch (ch) {
case 'a': /* print extended attributes *debug* */
- attrs = 1;
- break;
+ attrs = 1;
+ break;
case 'd': /* set debug level */
- debug_level = atoi(optarg);
- if (debug_level <= 0) {
- debug_level = 1;
- }
- break;
+ debug_level = atoi(optarg);
+ if (debug_level <= 0) {
+ debug_level = 1;
+ }
+ break;
case 'e': /* exclude patterns */
- exc = optarg;
- break;
+ exc = optarg;
+ break;
case 'i': /* include patterns */
- inc = optarg;
- break;
+ inc = optarg;
+ break;
case '?':
- default:
- usage();
+ default:
+ usage();
}
}
} else {
for (i=0; i < argc; i++) {
if (strcmp(argv[i], "-") == 0) {
- while (fgets(name, sizeof(name)-1, stdin)) {
- strip_trailing_junk(name);
- add_fname_to_include_list(ff, 0, name);
- }
- continue;
- }
- add_fname_to_include_list(ff, 0, argv[i]);
+ while (fgets(name, sizeof(name)-1, stdin)) {
+ strip_trailing_junk(name);
+ add_fname_to_include_list(ff, 0, name);
+ }
+ continue;
+ }
+ add_fname_to_include_list(ff, 0, argv[i]);
}
}
if (inc) {
fd = fopen(inc, "r");
if (!fd) {
printf("Could not open include file: %s\n", inc);
- exit(1);
+ exit(1);
}
while (fgets(name, sizeof(name)-1, fd)) {
- strip_trailing_junk(name);
- add_fname_to_include_list(ff, 0, name);
+ strip_trailing_junk(name);
+ add_fname_to_include_list(ff, 0, name);
}
fclose(fd);
}
fd = fopen(exc, "r");
if (!fd) {
printf("Could not open exclude file: %s\n", exc);
- exit(1);
+ exit(1);
}
while (fgets(name, sizeof(name)-1, fd)) {
- strip_trailing_junk(name);
- add_fname_to_exclude_list(ff, name);
+ strip_trailing_junk(name);
+ add_fname_to_exclude_list(ff, name);
}
fclose(fd);
}
exit(0);
}
-static int print_file(FF_PKT *ff, void *pkt)
+static int print_file(FF_PKT *ff, void *pkt, bool top_level)
{
switch (ff->type) {
case FT_DIREND:
if (debug_level) {
char errmsg[100] = "";
- if (ff->type == FT_NORECURSE) {
+ if (ff->type == FT_NORECURSE) {
bstrncpy(errmsg, "\t[will not descend: recursion turned off]", sizeof(errmsg));
- } else if (ff->type == FT_NOFSCHG) {
+ } else if (ff->type == FT_NOFSCHG) {
bstrncpy(errmsg, "\t[will not descend: file system change not allowed]", sizeof(errmsg));
- } else if (ff->type == FT_INVALIDFS) {
+ } else if (ff->type == FT_INVALIDFS) {
bstrncpy(errmsg, "\t[will not descend: disallowed file system]", sizeof(errmsg));
- }
+ }
printf("%s%s%s\n", (debug_level > 1 ? "Dir: " : ""), ff->fname, errmsg);
}
ff->type = FT_DIREND;
*/
for (p=l=ar->fname; *p; p++) {
if (*p == '/') {
- l = p; /* set pos of last slash */
+ l = p; /* set pos of last slash */
}
}
if (*l == '/') { /* did we find a slash? */
- l++; /* yes, point to filename */
- } else { /* no, whole thing must be path name */
+ l++; /* yes, point to filename */
+ } else { /* no, whole thing must be path name */
l = p;
}
trunc_fname++;
}
if (fnl > 0) {
- strncpy(file, l, fnl); /* copy filename */
+ strncpy(file, l, fnl); /* copy filename */
file[fnl] = 0;
} else {
file[0] = ' '; /* blank filename */
static JCR *jcr;
-static int print_file(FF_PKT *ff, void *pkt);
+static int print_file(FF_PKT *ff, void *pkt, bool);
static void print_ls_output(char *fname, char *link, int type, struct stat *statp);
static void usage()
while ((ch = getopt(argc, argv, "ad:e:i:?")) != -1) {
switch (ch) {
case 'a': /* print extended attributes *debug* */
- attrs = 1;
- break;
+ attrs = 1;
+ break;
case 'd': /* set debug level */
- debug_level = atoi(optarg);
- if (debug_level <= 0) {
- debug_level = 1;
- }
- break;
+ debug_level = atoi(optarg);
+ if (debug_level <= 0) {
+ debug_level = 1;
+ }
+ break;
case 'e': /* exclude patterns */
- exc = optarg;
- break;
+ exc = optarg;
+ break;
case 'i': /* include patterns */
- inc = optarg;
- break;
+ inc = optarg;
+ break;
case '?':
default:
- usage();
+ usage();
}
}
} else {
for (i=0; i < argc; i++) {
if (strcmp(argv[i], "-") == 0) {
- while (fgets(name, sizeof(name)-1, stdin)) {
- strip_trailing_junk(name);
- add_fname_to_include_list(ff, 0, name);
- }
- continue;
- }
- add_fname_to_include_list(ff, 0, argv[i]);
+ while (fgets(name, sizeof(name)-1, stdin)) {
+ strip_trailing_junk(name);
+ add_fname_to_include_list(ff, 0, name);
+ }
+ continue;
+ }
+ add_fname_to_include_list(ff, 0, argv[i]);
}
}
if (inc) {
fd = fopen(inc, "r");
if (!fd) {
printf("Could not open include file: %s\n", inc);
- exit(1);
+ exit(1);
}
while (fgets(name, sizeof(name)-1, fd)) {
- strip_trailing_junk(name);
- add_fname_to_include_list(ff, 0, name);
+ strip_trailing_junk(name);
+ add_fname_to_include_list(ff, 0, name);
}
fclose(fd);
}
fd = fopen(exc, "r");
if (!fd) {
printf("Could not open exclude file: %s\n", exc);
- exit(1);
+ exit(1);
}
while (fgets(name, sizeof(name)-1, fd)) {
- strip_trailing_junk(name);
- add_fname_to_exclude_list(ff, name);
+ strip_trailing_junk(name);
+ add_fname_to_exclude_list(ff, name);
}
fclose(fd);
}
exit(0);
}
-static int print_file(FF_PKT *ff, void *pkt)
+static int print_file(FF_PKT *ff, void *pkt, bool top_level)
{
switch (ff->type) {
*p++ = ' ';
/* Copy link name */
for (f=link; *f && (p-buf) < (int)sizeof(buf); )
- *p++ = *f++;
+ *p++ = *f++;
}
*p++ = '\n';
*p = 0;
/* */
#undef VERSION
#define VERSION "1.37.12"
-#define BDATE "05 April 2005"
-#define LSMDATE "05Apr05"
+#define BDATE "08 April 2005"
+#define LSMDATE "08Apr05"
/* Debug flags */
#undef DEBUG