+++ /dev/null
-
- This patch can be applied to version 3.0.1 and makes
- error conditions obtaining acls during backup non-fatal.
- This should fix bug #1305.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-acl-error.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/filed/acl.c
-===================================================================
---- src/filed/acl.c (revision 8902)
-+++ src/filed/acl.c (working copy)
-@@ -406,31 +406,35 @@
- pm_strcpy(jcr->acl_data, "");
- acl_free(acl);
-
-- return -1;
-+ return 0; /* non-fatal error */
- }
-
- /*
- * Handle errors gracefully.
- */
-- switch (errno) {
-+ if (acl == (acl_t)NULL) {
-+ switch (errno) {
- #if defined(BACL_ENOTSUP)
-- case BACL_ENOTSUP:
-- /*
-- * Not supported, just pretend there is nothing to see
-- */
-- pm_strcpy(jcr->acl_data, "");
-- return 0;
-+ case BACL_ENOTSUP:
-+ break; /* not supported */
- #endif
-- default:
-- berrno be;
-- Jmsg2(jcr, M_ERROR, 0, _("acl_get_file error on file \"%s\": ERR=%s\n"),
-- jcr->last_fname, be.bstrerror());
-- Dmsg2(100, "acl_get_file error file=%s ERR=%s\n",
-- jcr->last_fname, be.bstrerror());
-+ default:
-+ berrno be;
-+ /* Some real error */
-+ Jmsg2(jcr, M_ERROR, 0, _("acl_get_file error on file \"%s\": ERR=%s\n"),
-+ jcr->last_fname, be.bstrerror());
-+ Dmsg2(100, "acl_get_file error file=%s ERR=%s\n",
-+ jcr->last_fname, be.bstrerror());
-
-- pm_strcpy(jcr->acl_data, "");
-- return -1;
-+ pm_strcpy(jcr->acl_data, "");
-+ return 0; /* non-fatal error */
-+ }
- }
-+ /*
-+ * Not supported, just pretend there is nothing to see
-+ */
-+ pm_strcpy(jcr->acl_data, "");
-+ return 0;
- }
-
- /*
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and should
- fix bug #1309 btape fill multiple tape generates error but
- end of fill test says successful.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-btape.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/stored/btape.c
-===================================================================
---- src/stored/btape.c (revision 8902)
-+++ src/stored/btape.c (working copy)
-@@ -414,7 +414,6 @@
- }
- }
- dev->rewind(dcr);
-- dev->weof(1);
- write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
- Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
- }
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and should fix
- a crash in the SD that occurs after canceling a job.
- This should fix bug #1298.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-cancel-sd.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/stored/reserve.c
-===================================================================
---- src/stored/reserve.c (revision 8892)
-+++ src/stored/reserve.c (working copy)
-@@ -755,6 +755,9 @@
- bool ok = false;
-
- ASSERT(dcr);
-+ if (job_canceled(jcr)) {
-+ return false;
-+ }
-
- dev->dlock();
-
-@@ -809,6 +812,9 @@
- bool ok = false;
-
- ASSERT(dcr);
-+ if (job_canceled(jcr)) {
-+ return false;
-+ }
-
- dev->dlock();
-
-Index: src/stored/spool.c
-===================================================================
---- src/stored/spool.c (revision 8892)
-+++ src/stored/spool.c (working copy)
-@@ -436,6 +436,9 @@
- bool despool = false;
- DEV_BLOCK *block = dcr->block;
-
-+ if (job_canceled(dcr->jcr)) {
-+ return false;
-+ }
- ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
- if (block->binbuf <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */
- return true;
-Index: src/stored/vol_mgr.c
-===================================================================
---- src/stored/vol_mgr.c (revision 8892)
-+++ src/stored/vol_mgr.c (working copy)
-@@ -344,6 +344,9 @@
- VOLRES *vol, *nvol;
- DEVICE * volatile dev = dcr->dev;
-
-+ if (job_canceled(dcr->jcr)) {
-+ return NULL;
-+ }
- ASSERT(dev != NULL);
-
- Dmsg2(dbglvl, "enter reserve_volume=%s drive=%s\n", VolumeName,
-@@ -701,6 +704,9 @@
- bool rtn = true;
- VOLRES *vol;
-
-+ if (job_canceled(jcr)) {
-+ return false;
-+ }
- lock_volumes();
- vol = find_volume(VolumeName);
- if (!vol) {
-Index: src/stored/askdir.c
-===================================================================
---- src/stored/askdir.c (revision 8892)
-+++ src/stored/askdir.c (working copy)
-@@ -494,6 +494,9 @@
- JCR *jcr = dcr->jcr;
- bool got_vol = false;
-
-+ if (job_canceled(jcr)) {
-+ return false;
-+ }
- Dmsg0(400, "enter dir_ask_sysop_to_create_appendable_volume\n");
- ASSERT(dev->blocked());
- for ( ;; ) {
-Index: src/stored/block.c
-===================================================================
---- src/stored/block.c (revision 8892)
-+++ src/stored/block.c (working copy)
-@@ -415,6 +415,9 @@
- empty_block(block);
- return true;
- #endif
-+ if (job_canceled(jcr)) {
-+ return false;
-+ }
- ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
- ASSERT(dev->is_open());
-
-@@ -935,6 +938,9 @@
- DEVICE *dev = dcr->dev;
- DEV_BLOCK *block = dcr->block;
-
-+ if (job_canceled(jcr)) {
-+ return false;
-+ }
- ASSERT(dev->is_open());
-
- if (dev->at_eot()) {
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and should
- fix bug #1307 where a Job being escalated with
- Allow Higher Duplicates = no is cancelled.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-higher-duplicates.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (revision 8902)
-+++ src/dird/job.c (working copy)
-@@ -672,6 +672,9 @@
- if (!job->AllowHigherDuplicates) {
- foreach_jcr(djcr) {
- char ec1[50];
-+ if (jcr == djcr) {
-+ continue; /* do not cancel this job */
-+ }
- if (strcmp(job->name(), djcr->job->name()) == 0) {
- bool cancel_queued = false;
- if (job->DuplicateJobProximity > 0) {
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and fixes a
- IP address resolution priorities between ipv4 and ipv6.
- This should fix bug #1029
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-ipv6-resolution-order.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/lib/bnet.c
-===================================================================
---- src/lib/bnet.c (révision 8841)
-+++ src/lib/bnet.c (copie de travail)
-@@ -495,13 +495,16 @@
- return 0;
- }
- } else {
-- errmsg = resolv_host(AF_INET, host, addr_list);
- #ifdef HAVE_IPV6
-- if (errmsg) {
-- errmsg = resolv_host(AF_INET6, host, addr_list);
-- }
-+ /* We try to resolv host for ipv6 and ipv4, the connection procedure
-+ * will try to reach the host for each protocols. We report only "Host
-+ * not found" ipv4 message (no need to have ipv6 and ipv4 messages).
-+ */
-+ resolv_host(AF_INET6, host, addr_list);
- #endif
-- if (errmsg) {
-+ errmsg = resolv_host(AF_INET, host, addr_list);
-+
-+ if (addr_list->size() == 0) {
- *errstr = errmsg;
- free_addresses(addr_list);
- return 0;
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and ensures that
- if maxdiffinterval is set, it will be done even if no prior
- Diff job ran. This should fix bug #1311.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-maxdiff.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/fd_cmds.c
-===================================================================
---- src/dird/fd_cmds.c (revision 8911)
-+++ src/dird/fd_cmds.c (working copy)
-@@ -198,22 +198,33 @@
- now = (utime_t)time(NULL);
- jcr->jr.JobId = 0; /* flag to return since time */
- have_full = db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime);
-- /* If there was a successful job, make sure it is recent enough */
-- if (jcr->get_JobLevel() == L_INCREMENTAL && have_full && jcr->job->MaxDiffInterval > 0) {
-+ if (have_full) {
-+ last_full_time = str_to_utime(jcr->stime);
-+ } else {
-+ do_full = true; /* No full, upgrade to one */
-+ }
-+ /* Make sure the last diff is recent enough */
-+ if (have_full && jcr->get_JobLevel() == L_INCREMENTAL && jcr->job->MaxDiffInterval > 0) {
- /* Lookup last diff job */
- if (db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, L_DIFFERENTIAL)) {
- last_diff_time = str_to_utime(stime);
-- do_diff = ((now - last_diff_time) >= jcr->job->MaxDiffInterval);
-+ /* If no Diff since Full, use Full time */
-+ if (last_diff_time < last_full_time) {
-+ last_diff_time = last_full_time;
-+ }
-+ } else {
-+ /* No last differential, so use last full time */
-+ last_diff_time = last_full_time;
- }
-+ do_diff = ((now - last_diff_time) >= jcr->job->MaxDiffInterval);
- }
-- if (have_full && jcr->job->MaxFullInterval > 0 &&
-- db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, L_FULL)) {
-- last_full_time = str_to_utime(stime);
-+ /* Note, do_full takes precedence over do_diff */
-+ if (have_full && jcr->job->MaxFullInterval > 0) {
- do_full = ((now - last_full_time) >= jcr->job->MaxFullInterval);
- }
- free_pool_memory(stime);
-
-- if (!have_full || do_full) {
-+ if (do_full) {
- /* No recent Full job found, so upgrade this one to Full */
- Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db));
- Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing FULL backup.\n"));
-@@ -221,7 +232,7 @@
- level_to_str(jcr->get_JobLevel()));
- jcr->set_JobLevel(jcr->jr.JobLevel = L_FULL);
- } else if (do_diff) {
-- /* No recent diff job found, so upgrade this one to Full */
-+ /* No recent diff job found, so upgrade this one to Diff */
- Jmsg(jcr, M_INFO, 0, _("No prior or suitable Differential backup found in catalog. Doing Differential backup.\n"));
- bsnprintf(since, since_len, _(" (upgraded from %s)"),
- level_to_str(jcr->get_JobLevel()));
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and should improve
- error messages when a migration sql query is used and correct
- the problem identified in bug #1303 with starting Job names
- containing spaces.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-migrate-sql.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 8887)
-+++ src/dird/migrate.c (working copy)
-@@ -481,6 +481,12 @@
- {
- idpkt *ids = (idpkt *)ctx;
-
-+ /* Sanity check */
-+ if (!row || !row[0]) {
-+ Dmsg0(dbglevel, "dbid_hdlr error empty row\n");
-+ return 1; /* stop calling us */
-+ }
-+
- add_unique_id(ids, row[0]);
- Dmsg3(dbglevel, "dbid_hdlr count=%d Ids=%p %s\n", ids->count, ids->list, ids->list);
- return 0;
-@@ -847,9 +853,6 @@
- JobId = 0;
- stat = get_next_jobid_from_list(&p, &JobId);
- Dmsg3(dbglevel, "get_jobid_no=%d stat=%d JobId=%u\n", i, stat, JobId);
-- jcr->MigrateJobId = JobId;
-- start_migration_job(jcr);
-- Dmsg0(dbglevel, "Back from start_migration_job\n");
- if (stat < 0) {
- Jmsg(jcr, M_FATAL, 0, _("Invalid JobId found.\n"));
- goto bail_out;
-@@ -857,6 +860,9 @@
- Jmsg(jcr, M_INFO, 0, _("No JobIds found to %s.\n"), jcr->get_ActionName(0));
- goto ok_out;
- }
-+ jcr->MigrateJobId = JobId;
-+ start_migration_job(jcr);
-+ Dmsg0(dbglevel, "Back from start_migration_job\n");
- }
-
- /* Now get the last JobId and handle it in the current job */
-@@ -908,7 +914,7 @@
- UAContext *ua = new_ua_context(jcr);
- char ed1[50];
- ua->batch = true;
-- Mmsg(ua->cmd, "run %s jobid=%s", jcr->job->hdr.name,
-+ Mmsg(ua->cmd, "run job=\"%s\" jobid=%s", jcr->job->name(),
- edit_uint64(jcr->MigrateJobId, ed1));
- Dmsg2(dbglevel, "=============== %s cmd=%s\n", jcr->get_OperationName(), ua->cmd);
- parse_ua_args(ua); /* parse command */
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and fixes a
- a race condition that causes the SD to hang. This should
- fix bug #1287.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-sd-hang.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/lib/jcr.c
-===================================================================
---- src/lib/jcr.c (revision 8840)
-+++ src/lib/jcr.c (working copy)
-@@ -518,6 +518,7 @@
- jcr->JobId, jcr->use_count(), jcr->Job);
- }
- remove_jcr(jcr); /* remove Jcr from chain */
-+ unlock_jcr_chain();
-
- dequeue_messages(jcr);
- job_end_pop(jcr); /* pop and call hooked routines */
-@@ -571,7 +572,6 @@
- jcr->daemon_free_jcr(jcr); /* call daemon free routine */
- }
-
-- unlock_jcr_chain();
- free_common_jcr(jcr);
- close_msg(NULL); /* flush any daemon messages */
- garbage_collect_memory_pool();
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and fixes a
- syntax error that causes builds on older Solarises to fail.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-solaris-acl.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/filed/acl.c
-===================================================================
---- src/filed/acl.c (revision 8810)
-+++ src/filed/acl.c (working copy)
-@@ -1141,7 +1141,7 @@
- /*
- * OS specific functions for handling different types of acl streams.
- */
--static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt);
-+static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
- {
- int n;
- aclent_t *acls;
+++ /dev/null
-
- This patch can be applied to version 3.0.1 and modifies xattr
- handling to print warning or error messages when problems are
- found without canceling the Job. This patch *must* be applied
- after 3.0.1-acl-error.patch. It should fix the re-opened
- bug #1305.
-
- Apply it to version 3.0.1 with:
-
- cd <bacula-source>
- patch -p0 <3.0.1-xattr.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/filed/xattr.c
-===================================================================
---- src/filed/xattr.c (revision 8923)
-+++ src/filed/xattr.c (working copy)
-@@ -96,7 +96,6 @@
- if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
- Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- sd->bstrerror());
--
- return false;
- }
-
-@@ -112,7 +111,6 @@
- sd->msglen = 0;
- Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- sd->bstrerror());
--
- return false;
- }
-
-@@ -121,10 +119,8 @@
- if (!sd->signal(BNET_EOD)) {
- Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
- sd->bstrerror());
--
- return false;
- }
--
- Dmsg1(200, "XATTR of file: %s successfully backed up!\n", jcr->last_fname);
-
- return true;
-@@ -265,8 +261,7 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
-- return false;
-+ return true; /* non-fatal return */
- } else if (xattr_list_len == 0) {
- return true;
- }
-@@ -274,11 +269,7 @@
- /*
- * Allocate room for the extented attribute list.
- */
-- if ((xattr_list = (char *)malloc(xattr_list_len + 1)) == (char *)NULL) {
-- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_list_len + 1);
--
-- return false;
-- }
-+ xattr_list = (char *)malloc(xattr_list_len + 1);
- memset((caddr_t)xattr_list, 0, xattr_list_len + 1);
-
- /*
-@@ -291,10 +282,8 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
- free(xattr_list);
--
-- return false;
-+ return true; /* non-fatal return */
- }
- xattr_list[xattr_list_len] = '\0';
-
-@@ -328,11 +317,7 @@
- * Allocate enough room to hold all extended attributes.
- * After allocating the storage make sure its empty by zeroing it.
- */
-- if ((xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t))) == (xattr_t *)NULL) {
-- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), count * sizeof(xattr_t));
--
-- return false;
-- }
-+ xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t));
- memset((caddr_t)xattr_value_list, 0, count * sizeof(xattr_t));
-
- /*
-@@ -345,7 +330,6 @@
- #if defined(HAVE_LINUX_OS)
- if (ff_pkt->flags & FO_ACL && !strcmp(bp, "system.posix_acl_access")) {
- bp = strchr(bp, '\0') + 1;
--
- continue;
- }
- #endif
-@@ -360,11 +344,7 @@
- * Allocate space for storing the name.
- */
- current_xattr->name_length = strlen(bp);
-- if ((current_xattr->name = (char *)malloc(current_xattr->name_length)) == (char *)NULL) {
-- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr->name_length);
--
-- goto bail_out;
-- }
-+ current_xattr->name = (char *)malloc(current_xattr->name_length);
- memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length);
-
- expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length;
-@@ -379,18 +359,13 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
- goto bail_out;
- }
-
- /*
- * Allocate space for storing the value.
- */
-- if ((current_xattr->value = (char *)malloc(xattr_value_len)) == (char *)NULL) {
-- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_value_len);
--
-- goto bail_out;
-- }
-+ current_xattr->value = (char *)malloc(xattr_value_len);
- memset((caddr_t)current_xattr->value, 0, xattr_value_len);
-
- xattr_value_len = lgetxattr(jcr->last_fname, bp, current_xattr->value, xattr_value_len);
-@@ -400,7 +375,6 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
- goto bail_out;
- }
-
-@@ -416,7 +390,6 @@
- if (expected_serialize_len >= MAX_XATTR_STREAM) {
- Jmsg2(jcr, M_ERROR, 0, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
- jcr->last_fname, MAX_XATTR_STREAM);
--
- goto bail_out;
- }
-
-@@ -435,7 +408,6 @@
- jcr->last_fname);
- Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n",
- jcr->last_fname);
--
- goto bail_out;
- }
-
-@@ -450,15 +422,14 @@
- bail_out:
- xattr_drop_internal_table(xattr_value_list);
- free(xattr_list);
--
-- return false;
-+ return true; /* non-fatal return */
- }
-
- static bool generic_xattr_parse_streams(JCR *jcr)
- {
- unser_declare;
- xattr_t current_xattr;
-- bool retval = true;
-+ bool retval = true; /* default non-fatal */
-
- /*
- * Parse the stream and perform the setxattr calls on the file.
-@@ -478,8 +449,7 @@
- jcr->last_fname);
- Dmsg1(100, "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n",
- jcr->last_fname);
--
-- return false;
-+ return true; /* non-fatal return */
- }
-
- /*
-@@ -490,11 +460,7 @@
- /*
- * Allocate room for the name and decode its content.
- */
-- if ((current_xattr.name = (char *)malloc(current_xattr.name_length + 1)) == (char *)NULL) {
-- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.name_length + 1);
--
-- return false;
-- }
-+ current_xattr.name = (char *)malloc(current_xattr.name_length + 1);
- unser_bytes(current_xattr.name, current_xattr.name_length);
-
- /*
-@@ -510,11 +476,7 @@
- /*
- * Allocate room for the value and decode its content.
- */
-- if ((current_xattr.value = (char *)malloc(current_xattr.value_length)) == (char *)NULL) {
-- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.value_length);
--
-- return false;
-- }
-+ current_xattr.value = (char *)malloc(current_xattr.value_length);
- unser_bytes(current_xattr.value, current_xattr.value_length);
-
- /*
-@@ -529,12 +491,6 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "lsetxattr error file=%s ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
-- /*
-- * Reset the return flag to false to indicate one or more extended attributes
-- * could not be restored.
-- */
-- retval = false;
- }
-
- /*
-@@ -560,7 +516,10 @@
- case STREAM_XATTR_DARWIN:
- return generic_xattr_parse_streams(jcr);
- default:
-- return false;
-+ Jmsg2(jcr, M_WARNING, 0,
-+ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-+ jcr->last_fname, stream);
-+ return true; /* non-fatal error */
- }
- }
- #elif defined(HAVE_FREEBSD_OS)
-@@ -575,7 +534,10 @@
- case STREAM_XATTR_FREEBSD:
- return generic_xattr_parse_streams(jcr);
- default:
-- return false;
-+ Jmsg2(jcr, M_WARNING, 0,
-+ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-+ jcr->last_fname, stream);
-+ return true; /* non-fatal error */
- }
- }
- #elif defined(HAVE_LINUX_OS)
-@@ -590,7 +552,10 @@
- case STREAM_XATTR_LINUX:
- return generic_xattr_parse_streams(jcr);
- default:
-- return false;
-+ Jmsg2(jcr, M_WARNING, 0,
-+ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-+ jcr->last_fname, stream);
-+ return true; /* non-fatal error */
- }
- }
- #elif defined(HAVE_NETBSD_OS)
-@@ -605,7 +570,10 @@
- case STREAM_XATTR_NETBSD:
- return generic_xattr_parse_streams(jcr);
- default:
-- return false;
-+ Jmsg2(jcr, M_WARNING, 0,
-+ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-+ jcr->last_fname, stream);
-+ return true; /* non-fatal error */
- }
- }
- #endif
-@@ -726,10 +694,11 @@
- {
- xattr_link_cache_entry_t *ptr;
-
-- for (ptr = xattr_link_cache_head; ptr != NULL; ptr = ptr->next)
-- if (ptr->inum == inum)
-+ for (ptr = xattr_link_cache_head; ptr != NULL; ptr = ptr->next) {
-+ if (ptr->inum == inum) {
- return ptr;
--
-+ }
-+ }
- return NULL;
- }
-
-@@ -737,16 +706,16 @@
- {
- xattr_link_cache_entry_t *ptr;
-
-- if ((ptr = (xattr_link_cache_entry_t *)malloc(sizeof(struct xattr_link_cache_entry))) != NULL) {
-- memset((caddr_t)ptr, 0, sizeof(struct xattr_link_cache_entry));
-- ptr->inum = inum;
-- strncpy(ptr->target, target, sizeof(ptr->target));
-- if (xattr_link_cache_head == NULL)
-- xattr_link_cache_head = ptr;
-- if (xattr_link_cache_tail != NULL)
-- xattr_link_cache_tail->next = ptr;
-- xattr_link_cache_tail = ptr;
-+ ptr = (xattr_link_cache_entry_t *)malloc(sizeof(struct xattr_link_cache_entry));
-+ memset((caddr_t)ptr, 0, sizeof(struct xattr_link_cache_entry));
-+ ptr->inum = inum;
-+ strncpy(ptr->target, target, sizeof(ptr->target));
-+ if (xattr_link_cache_head == NULL) {
-+ xattr_link_cache_head = ptr;
- }
-+ if (xattr_link_cache_tail != NULL)
-+ xattr_link_cache_tail->next = ptr;
-+ }
- }
-
- static void drop_xattr_link_cache(void)
-@@ -757,7 +726,6 @@
- next = ptr->next;
- free(ptr);
- }
--
- xattr_link_cache_head = NULL;
- xattr_link_cache_tail = NULL;
- }
-@@ -828,9 +796,9 @@
- }
-
- cleanup:
-- if (response != NULL)
-+ if (response != NULL) {
- nvlist_free(response);
--
-+ }
- return retval;
- }
- #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
-@@ -847,19 +815,17 @@
-
- for (n = 0; n < count; n++) {
- ace = &entries[n];
--
- if (!(ace->a_type == USER_OBJ ||
- ace->a_type == GROUP_OBJ ||
- ace->a_type == OTHER_OBJ ||
- ace->a_type == CLASS_OBJ))
- return false;
- }
--
- return true;
- }
- #endif /* HAVE_ACL && !HAVE_EXTENDED_ACL */
-
--static bool solaris_archive_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
-+static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
- {
- #ifdef HAVE_ACL
- #ifdef HAVE_EXTENDED_ACL
-@@ -881,8 +847,7 @@
- attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n",
- attrname, jcr->last_fname, be.bstrerror());
--
-- return false;
-+ return true; /* non-fatal */
- }
-
- if (aclp != NULL) {
-@@ -912,10 +877,11 @@
- /*
- * See if this attribute has an ACL
- */
-- if (fd != -1)
-+ if (fd != -1) {
- n = facl(fd, GETACLCNT, 0, NULL);
-- else
-+ } else {
- n = acl(attrname, GETACLCNT, 0, NULL);
-+ }
-
- if (n >= MIN_ACL_ENTRIES) {
- acls = (aclent_t *)malloc(n * sizeof(aclent_t));
-@@ -926,9 +892,8 @@
- attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n",
- attrname, jcr->last_fname, be.bstrerror());
--
- free(acls);
-- return false;
-+ return true; /* non-fatal */
- }
-
- /*
-@@ -941,9 +906,8 @@
- attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n",
- attrname, jcr->last_fname, be.bstrerror());
--
- free(acls);
-- return false;
-+ return true; /* non-fatal */
- }
- } else {
- *acl_text = NULL;
-@@ -956,18 +920,19 @@
-
- return true;
- #endif /* HAVE_EXTENDED_ACL */
-+
- #else /* HAVE_ACL */
-- return NULL;
-+ return false; /* fatal return */
- #endif /* HAVE_ACL */
- }
-
- /*
- * Forward declaration for recursive function call.
- */
--static bool solaris_archive_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
-+static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
-
- /*
-- * Archive an extended or extensible attribute.
-+ * Save an extended or extensible attribute.
- * This is stored as an opaque stream of bytes with the following encoding:
- *
- * <xattr_name>\0<stat_buffer>\0<acl_string>\0<actual_xattr_data>
-@@ -981,7 +946,7 @@
- * acl_string is an acl text when a non trivial acl is set on the xattr.
- * actual_xattr_data is the content of the xattr file.
- */
--static bool solaris_archive_xattr(JCR *jcr, int fd, const char *xattr_namespace,
-+static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
- const char *attrname, bool toplevel_hidden_dir, int stream)
- {
- int cnt;
-@@ -993,7 +958,7 @@
- char *acl_text = NULL;
- char attribs[MAXSTRING];
- char buffer[BUFSIZ];
-- bool retval = false;
-+ bool retval = true; /* default is non-fatal */
-
- snprintf(target_attrname, sizeof(target_attrname), "%s%s", xattr_namespace, attrname);
-
-@@ -1006,7 +971,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1022,7 +986,7 @@
- /*
- * Get any acl on the xattr.
- */
-- if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
-+ if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
- goto cleanup;
-
- /*
-@@ -1033,15 +997,16 @@
- cnt = snprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c",
- target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
- break;
-+
- case S_IFDIR:
- /*
- * Get any acl on the xattr.
- */
-- if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
-+ if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
- goto cleanup;
-
- /*
-- * See if this is the toplevel_hidden_dir being archived.
-+ * See if this is the toplevel_hidden_dir being saved.
- */
- if (toplevel_hidden_dir) {
- /*
-@@ -1054,7 +1019,6 @@
- "%s%c%s%c%s%c",
- target_attrname, 0, attribs, 0,
- (acl_text) ? acl_text : "", 0);
--
- goto cleanup;
- } else {
- /*
-@@ -1088,7 +1052,7 @@
- retval = send_xattr_stream(jcr, stream);
-
- /*
-- * For a hard linked file we are ready now, no need to recursively archive the attributes.
-+ * For a hard linked file we are ready now, no need to recursively save the attributes.
- */
- goto cleanup;
- }
-@@ -1103,8 +1067,9 @@
- /*
- * Get any acl on the xattr.
- */
-- if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
-+ if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text)) {
- goto cleanup;
-+ }
-
- /*
- * Encode the stat struct into an ASCII representation.
-@@ -1123,10 +1088,10 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
- break;
-+
- case S_IFLNK:
- /*
- * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
-@@ -1138,7 +1103,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1154,9 +1118,10 @@
- retval = send_xattr_stream(jcr, stream);
-
- /*
-- * For a soft linked file we are ready now, no need to recursively archive the attributes.
-+ * For a soft linked file we are ready now, no need to recursively save the attributes.
- */
- goto cleanup;
-+
- default:
- goto cleanup;
- }
-@@ -1167,7 +1132,7 @@
- if (nr_xattr_saved == 0) {
- pm_memcpy(jcr->xattr_data, toplevel_hidden_dir_xattr_data, toplevel_hidden_dir_xattr_data_len);
- jcr->xattr_data_len = toplevel_hidden_dir_xattr_data_len;
-- send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
-+ retval = send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
- }
-
- pm_memcpy(jcr->xattr_data, buffer, cnt);
-@@ -1185,7 +1150,6 @@
- if (st.st_size >= MAX_XATTR_STREAM) {
- Jmsg2(jcr, M_ERROR, 0, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
- jcr->last_fname, MAX_XATTR_STREAM);
--
- goto cleanup;
- }
-
-@@ -1200,24 +1164,26 @@
- target_attrname, jcr->last_fname);
- Dmsg2(100, "read of data from xattr %s on \"%s\" failed\n",
- target_attrname, jcr->last_fname);
--
- goto cleanup;
- }
- }
- break;
-+
- default:
- break;
- }
-
-- retval = send_xattr_stream(jcr, stream);
-- nr_xattr_saved++;
-+ if (retval) {
-+ retval = send_xattr_stream(jcr, stream);
-+ nr_xattr_saved++;
-+ }
-
- /*
-- * Recursivly call solaris_archive_extended_attributes for archiving the attributes
-+ * Recursivly call solaris_save_extended_attributes for archiving the attributes
- * available on this extended attribute.
- */
- if (retval) {
-- retval = solaris_archive_xattrs(jcr, xattr_namespace, attrname);
-+ retval = solaris_save_xattrs(jcr, xattr_namespace, attrname);
-
- /*
- * The recursive call could change our working dir so change back to the wanted workdir.
-@@ -1228,28 +1194,28 @@
- jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n",
- jcr->last_fname, fd, be.bstrerror());
--
- goto cleanup;
- }
- }
-
- cleanup:
-- if (acl_text)
-+ if (acl_text) {
- free(acl_text);
-- if (attrfd != -1)
-+ }
-+ if (attrfd != -1) {
- close(attrfd);
--
-+ }
- return retval;
- }
-
--static bool solaris_archive_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
-+static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
- {
- const char *name;
- int fd, filefd = -1, attrdirfd = -1;
- DIR *dirp;
- struct dirent *dp;
- char current_xattr_namespace[PATH_MAX];
-- bool retval = false;
-+ bool retval = true; /* default non-fatal error */
-
- /*
- * Determine what argument to use. Use attr_parent when set
-@@ -1258,18 +1224,19 @@
- */
- if (attr_parent) {
- name = attr_parent;
-- if (xattr_namespace)
-+ if (xattr_namespace) {
- snprintf(current_xattr_namespace, sizeof(current_xattr_namespace), "%s%s/",
- xattr_namespace, attr_parent);
-- else
-- strcpy(current_xattr_namespace, "/");
-+ } else {
-+ strncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
-+ }
- } else {
- name = jcr->last_fname;
-- strcpy(current_xattr_namespace, "/");
-+ strncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
- }
-
- /*
-- * Open the file on which to archive the xattrs read-only.
-+ * Open the file on which to save the xattrs read-only.
- */
- if ((filefd = open(name, O_RDONLY | O_NONBLOCK)) < 0) {
- berrno be;
-@@ -1277,7 +1244,6 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1301,13 +1267,12 @@
- Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
- name, jcr->last_fname, be.bstrerror());
- }
--
- goto cleanup;
- }
-
- /*
- * We need to change into the attribute directory to determine if each of the
-- * attributes should be archived.
-+ * attributes should be saved.
- */
- if (fchdir(attrdirfd) < 0) {
- berrno be;
-@@ -1315,7 +1280,6 @@
- jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
- jcr->last_fname, attrdirfd, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1325,7 +1289,7 @@
- * And as we want this entry before anything else we better just save its data.
- */
- if (!attr_parent)
-- solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, ".",
-+ solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, ".",
- true, STREAM_XATTR_SOLARIS);
-
- if ((fd = dup(attrdirfd)) == -1 ||
-@@ -1381,23 +1345,22 @@
- if (!solaris_has_non_transient_extensible_attributes(filefd)) {
- Dmsg3(400, "Skipping transient extensible attributes %s%s on file \"%s\"\n",
- current_xattr_namespace, dp->d_name, jcr->last_fname);
--
- continue;
- }
-
- /*
-- * Archive the xattr.
-+ * Save the xattr.
- */
-- solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
-+ solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
- false, STREAM_XATTR_SOLARIS_SYS);
- continue;
- }
- #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
-
- /*
-- * Archive the xattr.
-+ * Save the xattr.
- */
-- solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
-+ solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
- false, STREAM_XATTR_SOLARIS);
- }
-
-@@ -1409,7 +1372,6 @@
- close(attrdirfd);
- if (filefd != -1)
- close(filefd);
--
- return retval;
- }
-
-@@ -1421,7 +1383,9 @@
- acl_t *aclp = NULL;
-
- if ((error = acl_fromtext(acl_text, &aclp)) != 0) {
-- return false;
-+ Jmsg1(jcr, M_ERROR, 0, _("Unable to convert acl from text on file \"%s\"\n"
-+ jcr->last_fname));
-+ return true; /* non-fatal */
- }
-
- if ((fd != -1 && facl_set(fd, aclp) != 0) ||
-@@ -1431,14 +1395,14 @@
- attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
- attrname, jcr->last_fname, be.bstrerror());
--
-- return false;
-+ return true; /* non-fatal */
- }
-
-- if (aclp)
-+ if (aclp) {
- acl_free(aclp);
--
-+ }
- return true;
-+
- #else /* HAVE_EXTENDED_ACL */
- int n;
- aclent_t *acls = NULL;
-@@ -1452,16 +1416,17 @@
- attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
- attrname, jcr->last_fname, be.bstrerror());
--
-- return false;
-+ return true; /* non-fatal */
- }
- }
-
-- if (acls)
-+ if (acls) {
- free(acls);
--
-+ }
- return true;
-+
- #endif /* HAVE_EXTENDED_ACL */
-+
- }
- #endif /* HAVE_ACL */
-
-@@ -1476,7 +1441,7 @@
- int32_t inum;
- struct stat st;
- struct timeval times[2];
-- bool retval = false;
-+ bool retval = true; /* default non-fatal */
-
- /*
- * Parse the xattr stream. First the part that is the same for all xattrs.
-@@ -1505,7 +1470,6 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1518,7 +1482,6 @@
- jcr->last_fname, be.bstrerror());
- Dmsg2(100, "Unable to open xattr space on file \"%s\": ERR=%s\n",
- jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1528,7 +1491,6 @@
- jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
- jcr->last_fname, attrdirfd, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1546,7 +1508,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1562,7 +1523,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1578,7 +1538,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg4(100, "Unable to fchdir to xattr space %s on file \"%s\" using fd %d: ERR=%s\n",
- target_attrname, jcr->last_fname, attrdirfd, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1616,8 +1575,7 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
-- goto cleanup;
-+ goto cleanup;
- }
- break;
- case S_IFCHR:
-@@ -1632,7 +1590,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to mknod xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
- break;
-@@ -1649,7 +1606,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
- }
-@@ -1668,7 +1624,6 @@
- target_attrname, linked_target, jcr->last_fname, be.bstrerror());
- Dmsg4(100, "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n",
- target_attrname, linked_target, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1699,7 +1654,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
- }
-@@ -1720,7 +1674,6 @@
- target_attrname, jcr->last_fname);
- Dmsg2(100, "Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n",
- target_attrname, jcr->last_fname);
--
- goto cleanup;
- }
-
-@@ -1732,7 +1685,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1754,7 +1706,6 @@
- target_attrname, linked_target, jcr->last_fname, be.bstrerror());
- Dmsg4(100, "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n",
- target_attrname, linked_target, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
-
-@@ -1787,7 +1738,6 @@
- Dmsg3(100, "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
- }
--
- goto cleanup;
- }
- }
-@@ -1813,7 +1763,6 @@
- target_attrname, jcr->last_fname, be.bstrerror());
- Dmsg3(100, "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n",
- target_attrname, jcr->last_fname, be.bstrerror());
--
- goto cleanup;
- }
- }
-@@ -1831,13 +1780,15 @@
- jcr->last_fname);
-
- cleanup:
-- if (attrfd != -1)
-+ if (attrfd != -1) {
- close(attrfd);
-- if (attrdirfd != -1)
-+ }
-+ if (attrdirfd != -1) {
- close(attrdirfd);
-- if (filefd != -1)
-+ }
-+ if (filefd != -1) {
- close(filefd);
--
-+ }
- return retval;
- }
-
-@@ -1859,8 +1810,7 @@
- jcr->last_fname);
- Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n",
- jcr->last_fname);
--
-- return false;
-+ return true;
- }
-
- is_extensible = true;
-@@ -1873,13 +1823,11 @@
- jcr->last_fname);
- Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n",
- jcr->last_fname);
--
-- return false;
-+ return true;
- }
--
- break;
- default:
-- return false;
-+ return true;
- }
-
- /*
-@@ -1889,7 +1837,6 @@
- getcwd(cwd, sizeof(cwd));
- retval = solaris_restore_xattrs(jcr, is_extensible);
- chdir(cwd);
--
- return retval;
- }
-
-@@ -1906,13 +1853,12 @@
- nr_xattr_saved = 0;
-
- /*
-- * As we change the cwd in the archive function save the current cwd
-- * for restore after return from the solaris_archive_xattrs function.
-+ * As we change the cwd in the save function save the current cwd
-+ * for restore after return from the solaris_save_xattrs function.
- */
- getcwd(cwd, sizeof(cwd));
-- retval = solaris_archive_xattrs(jcr, NULL, NULL);
-+ retval = solaris_save_xattrs(jcr, NULL, NULL);
- chdir(cwd);
--
- drop_xattr_link_cache();
- }
-
-@@ -1928,7 +1874,10 @@
- case STREAM_XATTR_SOLARIS:
- return solaris_extract_xattr(jcr, stream);
- default:
-- return false;
-+ Jmsg2(jcr, M_WARNING, 0,
-+ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
-+ jcr->last_fname, stream);
-+ return true; /* non-fatal error */
- }
- }
- #endif
+++ /dev/null
-From 729f8b83b1002ae272e75a6139631846946f728f Mon Sep 17 00:00:00 2001
-From: Kern Sibbald <kern@sibbald.com>
-Date: Thu, 10 Sep 2009 15:19:13 +0200
-Subject: [PATCH] Add more info when SD connection refused
-
-as mentioned in bug #1371
----
- bacula/src/stored/dircmd.c | 4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c
-index 4f4a2d7..b011802 100644
---- a/bacula/src/stored/dircmd.c
-+++ b/bacula/src/stored/dircmd.c
-@@ -152,7 +152,7 @@ void *handle_connection_request(void *arg)
- char tbuf[100];
-
- if (bs->recv() <= 0) {
-- Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
-+ Emsg1(M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
- bs->close();
- return NULL;
- }
-@@ -162,7 +162,7 @@ void *handle_connection_request(void *arg)
- */
- if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)) {
- Dmsg1(000, "<filed: %s", bs->msg);
-- Emsg1(M_ERROR, 0, _("Invalid connection. Len=%d\n"), bs->msglen);
-+ Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), bs->who(), bs->msglen);
- bs->close();
- return NULL;
- }
---
-1.6.4.2
-
+++ /dev/null
-From 47110b209cb516100d4e3af861b18d5836a585e6 Mon Sep 17 00:00:00 2001
-From: Kern Sibbald <kern@sibbald.com>
-Date: Thu, 10 Sep 2009 15:28:59 +0200
-Subject: [PATCH] Fix seg fault in SD bug #1371
-
----
- bacula/src/lib/message.c | 17 +++++++++++------
- 1 files changed, 11 insertions(+), 6 deletions(-)
-
-diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c
-index 7acf744..bc527a7 100644
---- a/bacula/src/lib/message.c
-+++ b/bacula/src/lib/message.c
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
-
- The main author of Bacula is Kern Sibbald, with contributions from
- many others, a complete list can be found in the file AUTHORS.
-@@ -69,8 +69,8 @@ void create_jcr_key();
-
- /* Static storage */
-
--/* Used to allow only one thread close the daemon messages at a time */
--static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-+/* Allow only one thread to tweak d->fd at a time */
-+static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
- static MSGS *daemon_msgs; /* global messages */
- static char *catalog_db = NULL; /* database type */
- static void (*message_callback)(int type, char *msg) = NULL;
-@@ -421,7 +421,6 @@ void close_msg(JCR *jcr)
-
- if (jcr == NULL) { /* NULL -> global chain */
- msgs = daemon_msgs;
-- P(mutex); /* only one thread walking the chain */
- } else {
- msgs = jcr->jcr_msgs;
- jcr->jcr_msgs = NULL;
-@@ -429,6 +428,7 @@ void close_msg(JCR *jcr)
- if (msgs == NULL) {
- return;
- }
-+ P(fides_mutex);
- Dmsg1(850, "===Begin close msg resource at %p\n", msgs);
- cmd = get_pool_memory(PM_MESSAGE);
- for (d=msgs->dest_chain; d; ) {
-@@ -512,13 +512,12 @@ rem_temp_file:
- }
- d = d->next; /* point to next buffer */
- }
-+ V(fides_mutex);
- free_pool_memory(cmd);
- Dmsg0(850, "Done walking message chain.\n");
- if (jcr) {
- free_msgs_res(msgs);
- msgs = NULL;
-- } else {
-- V(mutex);
- }
- Dmsg0(850, "===End close msg resource\n");
- }
-@@ -737,6 +736,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
- case MD_MAIL_ON_ERROR:
- case MD_MAIL_ON_SUCCESS:
- Dmsg1(850, "MAIL for following msg: %s", msg);
-+ P(fides_mutex);
- if (!d->fd) {
- POOLMEM *name = get_pool_memory(PM_MESSAGE);
- make_unique_mail_filename(jcr, name, d);
-@@ -748,6 +748,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
- be.bstrerror());
- d->fd = NULL;
- free_pool_memory(name);
-+ V(fides_mutex);
- break;
- }
- d->mail_filename = name;
-@@ -758,6 +759,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
- d->max_len = len; /* keep max line length */
- }
- fputs(msg, d->fd);
-+ V(fides_mutex);
- break;
- case MD_APPEND:
- Dmsg1(850, "APPEND for following msg: %s", msg);
-@@ -767,7 +769,9 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
- Dmsg1(850, "FILE for following msg: %s", msg);
- mode = "w+b";
- send_to_file:
-+ P(fides_mutex);
- if (!d->fd && !open_dest_file(jcr, d, mode)) {
-+ V(fides_mutex);
- break;
- }
- fputs(dt, d->fd);
-@@ -781,6 +785,7 @@ send_to_file:
- fputs(msg, d->fd);
- }
- }
-+ V(fides_mutex);
- break;
- case MD_DIRECTOR:
- Dmsg1(850, "DIRECTOR for following msg: %s", msg);
---
-1.6.4.2
-
+++ /dev/null
-
- This patch can be applied to version 3.0.2 and fixes
- bug #1355 'bacula director crashes with double free
- in Accurate SQL query'
-
- Apply it to version 3.0.2 with:
-
- cd <bacula-source>
- patch -p2 <3.0.2-accurate.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h
-index 2ff803f..be07e84 100644
---- a/bacula/src/cats/cats.h
-+++ b/bacula/src/cats/cats.h
-@@ -1037,6 +1037,16 @@ struct db_int64_ctx {
- int count; /* number of values seen */
- };
-
-+/* Call back context for getting a list of comma separated strings from the database */
-+class db_list_ctx {
-+public:
-+ POOLMEM *list; /* list */
-+ int count; /* number of values seen */
-+
-+ db_list_ctx() { list = get_pool_memory(PM_FNAME); *list = 0; count = 0; }
-+ ~db_list_ctx() { free_pool_memory(list); list = NULL; }
-+};
-+
-
- #include "protos.h"
- #include "jcr.h"
-diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h
-index ea03a3c..565526a 100644
---- a/bacula/src/cats/protos.h
-+++ b/bacula/src/cats/protos.h
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
-
- The main author of Bacula is Kern Sibbald, with contributions from
- many others, a complete list can be found in the file AUTHORS.
-@@ -57,6 +57,7 @@ bool db_sql_query(B_DB *mdb, const char *cmd, DB_RESULT_HANDLER *result_handler,
- void db_start_transaction(JCR *jcr, B_DB *mdb);
- void db_end_transaction(JCR *jcr, B_DB *mdb);
- int db_int64_handler(void *ctx, int num_fields, char **row);
-+int db_list_handler(void *ctx, int num_fields, char **row);
- void db_thread_cleanup();
- void _dbg_print_db(JCR *jcr, FILE *fp);
-
-@@ -106,8 +107,8 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr);
- int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
- bool db_get_query_dbids(JCR *jcr, B_DB *mdb, POOL_MEM &query, dbid_list &ids);
- bool db_get_file_list(JCR *jcr, B_DB *mdb, char *jobids, DB_RESULT_HANDLER *result_handler, void *ctx);
--bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *jobids);
--int db_get_int_handler(void *ctx, int num_fields, char **row);
-+bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, db_list_ctx *jobids);
-+int db_get_int_handler(void *list, int num_fields, char **row);
-
-
- /* sql_list.c */
-diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c
-index 324d017..e698b5a 100644
---- a/bacula/src/cats/sql.c
-+++ b/bacula/src/cats/sql.c
-@@ -144,7 +144,21 @@ int db_int64_handler(void *ctx, int num_fields, char **row)
- return 0;
- }
-
--
-+/*
-+ * Use to build a comma separated list of values from a query. "10,20,30"
-+ */
-+int db_list_handler(void *ctx, int num_fields, char **row)
-+{
-+ db_list_ctx *lctx = (db_list_ctx *)ctx;
-+ if (num_fields == 1 && row[0]) {
-+ if (lctx->list[0]) {
-+ pm_strcat(lctx->list, ",");
-+ }
-+ pm_strcat(lctx->list, row[0]);
-+ lctx->count++;
-+ }
-+ return 0;
-+}
-
- /* NOTE!!! The following routines expect that the
- * calling subroutine sets and clears the mutex
-diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c
-index b9d25bb..62cd07c 100644
---- a/bacula/src/cats/sql_get.c
-+++ b/bacula/src/cats/sql_get.c
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
-
- The main author of Bacula is Kern Sibbald, with contributions from
- many others, a complete list can be found in the file AUTHORS.
-@@ -1100,7 +1100,7 @@ bool db_get_file_list(JCR *jcr, B_DB *mdb, char *jobids,
- * TODO: look and merge from ua_restore.c
- */
- bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
-- JOB_DBR *jr, POOLMEM *jobids)
-+ JOB_DBR *jr, db_list_ctx *jobids)
- {
- bool ret=false;
- char clientid[50], jobid[50], filesetid[50];
-@@ -1111,7 +1111,8 @@ bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
- time_t StartTime = (jr->StartTime)?jr->StartTime:time(NULL);
-
- bstrutime(date, sizeof(date), StartTime + 1);
-- jobids[0]='\0';
-+ jobids->list[0] = 0;
-+ jobids->count = 0;
-
- /* First, find the last good Full backup for this job/client/fileset */
- Mmsg(query,
-@@ -1177,8 +1178,8 @@ bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
-
- /* build a jobid list ie: 1,2,3,4 */
- Mmsg(query, "SELECT JobId FROM btemp3%s ORDER by JobTDate", jobid);
-- db_sql_query(mdb, query.c_str(), db_get_int_handler, jobids);
-- Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids);
-+ db_sql_query(mdb, query.c_str(), db_list_handler, jobids);
-+ Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids->list);
- ret = true;
-
- bail_out:
-@@ -1188,19 +1189,4 @@ bail_out:
- return ret;
- }
-
--/*
-- * Use to build a string of int list from a query. "10,20,30"
-- */
--int db_get_int_handler(void *ctx, int num_fields, char **row)
--{
-- POOLMEM *ret = (POOLMEM *)ctx;
-- if (num_fields == 1) {
-- if (ret[0]) {
-- pm_strcat(ret, ",");
-- }
-- pm_strcat(ret, row[0]);
-- }
-- return 0;
--}
--
- #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL || HAVE_DBI */
-diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c
-index 029dfa0..1837a6b 100644
---- a/bacula/src/dird/backup.c
-+++ b/bacula/src/dird/backup.c
-@@ -131,42 +131,37 @@ static int accurate_list_handler(void *ctx, int num_fields, char **row)
- bool send_accurate_current_files(JCR *jcr)
- {
- POOL_MEM buf;
-+ db_list_ctx jobids;
-+ db_list_ctx nb;
-
- if (!jcr->accurate || job_canceled(jcr) || jcr->get_JobLevel()==L_FULL) {
- return true;
- }
-- POOLMEM *jobids = get_pool_memory(PM_FNAME);
-
-- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
--
-- if (*jobids == 0) {
-- free_pool_memory(jobids);
-+ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
-+ if (jobids.count == 0) {
- Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
- return false;
- }
-+
- if (jcr->JobId) { /* display the message only for real jobs */
- Jmsg(jcr, M_INFO, 0, _("Sending Accurate information.\n"));
- }
- /* to be able to allocate the right size for htable */
-- POOLMEM *nb = get_pool_memory(PM_FNAME);
-- *nb = 0; /* clear buffer */
-- Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)",jobids);
-- db_sql_query(jcr->db, buf.c_str(), db_get_int_handler, nb);
-- Dmsg2(200, "jobids=%s nb=%s\n", jobids, nb);
-- jcr->file_bsock->fsend("accurate files=%s\n", nb);
-+ Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)",jobids.list);
-+ db_sql_query(jcr->db, buf.c_str(), db_list_handler, &nb);
-+ Dmsg2(200, "jobids=%s nb=%s\n", jobids.list, nb.list);
-+ jcr->file_bsock->fsend("accurate files=%s\n", nb.list);
-
- if (!db_open_batch_connexion(jcr, jcr->db)) {
- Jmsg0(jcr, M_FATAL, 0, "Can't get dedicate sql connexion");
- return false;
- }
-
-- db_get_file_list(jcr, jcr->db_batch, jobids, accurate_list_handler, (void *)jcr);
-+ db_get_file_list(jcr, jcr->db_batch, jobids.list, accurate_list_handler, (void *)jcr);
-
- /* TODO: close the batch connexion ? (can be used very soon) */
-
-- free_pool_memory(jobids);
-- free_pool_memory(nb);
--
- jcr->file_bsock->signal(BNET_EOD);
-
- return true;
-diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c
-index 3d5fc1d..028be52 100644
---- a/bacula/src/dird/ua_output.c
-+++ b/bacula/src/dird/ua_output.c
-@@ -456,7 +456,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
- }
- list_nextvol(ua, n);
- } else if (strcasecmp(ua->argk[i], NT_("copies")) == 0) {
-- char *jobids=NULL;
-+ char *jobids = NULL;
- uint32_t limit=0;
- for (j=i+1; j<ua->argc; j++) {
- if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
-diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c
-index 366d9ed..16f5215 100644
---- a/bacula/src/dird/ua_restore.c
-+++ b/bacula/src/dird/ua_restore.c
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
-+ Copyright (C) 2002-2009 Free Software Foundation Europe e.V.
-
- The main author of Bacula is Kern Sibbald, with contributions from
- many others, a complete list can be found in the file AUTHORS.
-@@ -556,6 +556,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
- char *fname;
- int len;
- bool gui_save;
-+ db_list_ctx jobids;
-
- start_prompt(ua, _("To select the JobIds, you have the following choices:\n"));
- for (int i=0; list[i]; i++) {
-@@ -752,9 +753,10 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
- return 0;
- }
- jr.JobLevel = L_INCREMENTAL; /* Take Full+Diff+Incr */
-- if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, rx->JobIds)) {
-+ if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, &jobids)) {
- return 0;
- }
-+ pm_strcpy(rx->JobIds, jobids.list);
- Dmsg1(30, "Item 12: jobids = %s\n", rx->JobIds);
- break;
- case 12: /* Cancel or quit */
-diff --git a/bacula/src/dird/vbackup.c b/bacula/src/dird/vbackup.c
-index 45a1f7e..e75d08d 100644
---- a/bacula/src/dird/vbackup.c
-+++ b/bacula/src/dird/vbackup.c
-@@ -50,7 +50,7 @@
-
- static const int dbglevel = 10;
-
--static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids);
-+static bool create_bootstrap_file(JCR *jcr, char *jobids);
- void vbackup_cleanup(JCR *jcr, int TermCode);
-
- /*
-@@ -135,6 +135,7 @@ bool do_vbackup(JCR *jcr)
- char ed1[100];
- BSOCK *sd;
- char *p;
-+ db_list_ctx jobids;
-
- Dmsg2(100, "rstorage=%p wstorage=%p\n", jcr->rstorage, jcr->wstorage);
- Dmsg2(100, "Read store=%s, write store=%s\n",
-@@ -157,28 +158,27 @@ bool do_vbackup(JCR *jcr)
- _("This Job is not an Accurate backup so is not equivalent to a Full backup.\n"));
- }
-
-- POOLMEM *jobids = get_pool_memory(PM_FNAME);
- jcr->jr.JobLevel = L_VIRTUAL_FULL;
-- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
-- jcr->jr.JobLevel = L_FULL;
-- Dmsg1(10, "Accurate jobids=%s\n", jobids);
-- if (*jobids == 0) {
-- free_pool_memory(jobids);
-+ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
-+ Dmsg1(10, "Accurate jobids=%s\n", jobids.list);
-+ if (jobids.count == 0) {
- Jmsg(jcr, M_FATAL, 0, _("No previous Jobs found.\n"));
- return false;
- }
-
-+ jcr->jr.JobLevel = L_FULL;
-+
- /*
- * Now we find the last job that ran and store it's info in
- * the previous_jr record. We will set our times to the
- * values from that job so that anything changed after that
- * time will be picked up on the next backup.
- */
-- p = strrchr(jobids, ','); /* find last jobid */
-+ p = strrchr(jobids.list, ','); /* find last jobid */
- if (p != NULL) {
- p++;
- } else {
-- p = jobids;
-+ p = jobids.list;
- }
- memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
- jcr->previous_jr.JobId = str_to_int64(p);
-@@ -189,12 +189,10 @@ _("This Job is not an Accurate backup so is not equivalent to a Full backup.\n")
- return false;
- }
-
-- if (!create_bootstrap_file(jcr, jobids)) {
-+ if (!create_bootstrap_file(jcr, jobids.list)) {
- Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
-- free_pool_memory(jobids);
- return false;
- }
-- free_pool_memory(jobids);
-
- /*
- * Open a message channel connection with the Storage
-@@ -476,7 +474,7 @@ int insert_bootstrap_handler(void *ctx, int num_fields, char **row)
- }
-
-
--static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids)
-+static bool create_bootstrap_file(JCR *jcr, char *jobids)
- {
- RESTORE_CTX rx;
- UAContext *ua;
+++ /dev/null
->From f182fe49fca2b2e3009f26fbf6197f8c046835ad Mon Sep 17 00:00:00 2001
-From: Marco van Wieringen <mvw@planets.elm.net>
-Date: Sun, 6 Sep 2009 17:56:20 +0200
-Subject: [PATCH] This patch should fix bug #1365
-
----
- bacula/src/filed/restore.c | 15 +++++++--------
- 1 files changed, 7 insertions(+), 8 deletions(-)
-
-diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c
-index a4ee03a..4400e14 100644
---- a/bacula/src/filed/restore.c
-+++ b/bacula/src/filed/restore.c
-@@ -120,7 +120,7 @@ static void close_previous_stream(r_ctx &rctx);
-
-
- static bool verify_signature(JCR *jcr, r_ctx &rctx);
--int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
-+int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
- uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
- bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
- RESTORE_CIPHER_CTX *cipher_ctx);
-@@ -508,8 +508,9 @@ void do_restore(JCR *jcr)
- rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
- }
-
-- if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fileAddr,
-+ if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr,
- rctx.flags, &rctx.cipher_ctx) < 0) {
-+ rctx.extract = false;
- bclose(&rctx.bfd);
- continue;
- }
-@@ -558,8 +559,9 @@ void do_restore(JCR *jcr)
- Dmsg0(130, "Restoring resource fork\n");
- }
-
-- if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
-+ if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
- &rctx.fork_cipher_ctx) < 0) {
-+ rctx.extract = false;
- bclose(&rctx.forkbfd);
- continue;
- }
-@@ -1069,10 +1071,9 @@ bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win
- * The flags specify whether to use sparse files or compression.
- * Return value is the number of bytes written, or -1 on errors.
- */
--int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
-- uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
-+int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
-+ uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
- {
-- BFILE *bfd = &rctx.bfd;
- char *wbuf; /* write buffer */
- uint32_t wsize; /* write size */
- uint32_t rsize; /* read size */
-@@ -1172,9 +1173,7 @@ int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
- return wsize;
-
- bail_out:
-- rctx.extract = false;
- return -1;
--
- }
-
-
---
-1.5.6.5
-
+++ /dev/null
->From 297ec720cf512a6b5045c962bfb8a2f134ac77b0 Mon Sep 17 00:00:00 2001
-From: Marco van Wieringen <mvw@planets.elm.net>
-Date: Sun, 6 Sep 2009 18:06:48 +0200
-Subject: [PATCH] This patch should fix bug #1366
-
----
- bacula/src/filed/restore.c | 11 ++++++++++-
- 1 files changed, 10 insertions(+), 1 deletions(-)
-
-diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c
-index 4400e14..cbb0889 100644
---- a/bacula/src/filed/restore.c
-+++ b/bacula/src/filed/restore.c
-@@ -367,7 +367,6 @@ void do_restore(JCR *jcr)
- rctx.extract = true;
- /* FALLTHROUGH */
- case CF_CREATED: /* File created, but there is no content */
-- jcr->JobFiles++;
- rctx.fileAddr = 0;
- print_ls_output(jcr, attr);
-
-@@ -377,7 +376,17 @@ void do_restore(JCR *jcr)
- if (attr->type == FT_REG && rsrc_len > 0) {
- rctx.extract = true;
- }
-+
-+ /*
-+ * Count the resource forks not as regular files being restored.
-+ */
-+ if (rsrc_len == 0) {
-+ jcr->JobFiles++;
-+ }
-+ } else {
-+ jcr->JobFiles++;
- }
-+
- if (!rctx.extract) {
- /* set attributes now because file will not be extracted */
- if (jcr->plugin) {
---
-1.5.6.5
-
+++ /dev/null
-From 4d2f1c844510c9abb9ecf6f0283437862c4a3bfb Mon Sep 17 00:00:00 2001
-From: Eric Bollengier <eric@eb.homelinux.org>
-Date: Wed, 9 Sep 2009 14:18:57 +0200
-Subject: [PATCH] Fix #1370 about the implementation of the "Exclude Dir Containing" option on FD.
-
----
- bacula/src/filed/job.c | 20 +++++++++++---------
- bacula/src/findlib/find.c | 3 ++-
- bacula/src/findlib/find.h | 2 +-
- 3 files changed, 14 insertions(+), 11 deletions(-)
-
-diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c
-index 4054b29..549d6b7 100644
---- a/bacula/src/filed/job.c
-+++ b/bacula/src/filed/job.c
-@@ -342,13 +342,13 @@ void *handle_client_request(void *dirp)
- fo->base.destroy();
- fo->fstype.destroy();
- fo->drivetype.destroy();
-- if (fo->ignoredir != NULL) {
-- free(fo->ignoredir);
-- }
- }
- incexe->opts_list.destroy();
- incexe->name_list.destroy();
- incexe->plugin_list.destroy();
-+ if (incexe->ignoredir) {
-+ free(incexe->ignoredir);
-+ }
- }
- fileset->include_list.destroy();
-
-@@ -371,6 +371,9 @@ void *handle_client_request(void *dirp)
- incexe->opts_list.destroy();
- incexe->name_list.destroy();
- incexe->plugin_list.destroy();
-+ if (incexe->ignoredir) {
-+ free(incexe->ignoredir);
-+ }
- }
- fileset->exclude_list.destroy();
- free(fileset);
-@@ -876,9 +879,8 @@ static void add_fileset(JCR *jcr, const char *item)
- state = state_options;
- break;
- case 'Z':
-- current_opts = start_options(ff);
-- current_opts->ignoredir = bstrdup(item);
-- state = state_options;
-+ state = state_include;
-+ fileset->incexe->ignoredir = bstrdup(item);
- break;
- case 'D':
- current_opts = start_options(ff);
-@@ -941,9 +943,9 @@ static bool term_fileset(JCR *jcr)
- for (k=0; k<fo->drivetype.size(); k++) {
- Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
- }
-- if (fo->ignoredir) {
-- Dmsg1(400, "Z %s\n", fo->ignoredir);
-- }
-+ }
-+ if (incexe->ignoredir) {
-+ Dmsg1(400, "Z %s\n", incexe->ignoredir);
- }
- dlistString *node;
- foreach_dlist(node, &incexe->name_list) {
-diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c
-index 81e887a..d089b70 100644
---- a/bacula/src/findlib/find.c
-+++ b/bacula/src/findlib/find.c
-@@ -274,11 +274,12 @@ static bool accept_file(FF_PKT *ff)
- basename = ff->fname;
- }
-
-+ ff->ignoredir = incexe->ignoredir;
-+
- 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->ignoredir = fo->ignoredir;
- ff->fstypes = fo->fstype;
- ff->drivetypes = fo->drivetype;
-
-diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h
-index 030aa3f..ff9be47 100644
---- a/bacula/src/findlib/find.h
-+++ b/bacula/src/findlib/find.h
-@@ -151,7 +151,6 @@ struct findFOPTS {
- alist base; /* list of base names */
- alist fstype; /* file system type limitation */
- alist drivetype; /* drive type limitation */
-- char *ignoredir; /* ignore directories with this file */
- };
-
-
-@@ -161,6 +160,7 @@ struct findINCEXE {
- alist opts_list; /* options list */
- dlist name_list; /* filename list -- holds dlistString */
- dlist plugin_list; /* plugin list -- holds dlistString */
-+ char *ignoredir; /* ignore directories with this file */
- };
-
- /*
---
-1.6.3.1
-
+++ /dev/null
-From aaf17ad370610f17fc998ff9aeb9e6d9e8832787 Mon Sep 17 00:00:00 2001
-From: Eric Bollengier <eric@eb.homelinux.org>
-Date: Wed, 9 Sep 2009 16:46:36 +0200
-Subject: [PATCH 4/4] Fix Exclude Dir Containing ignored when scanning the top_level dir
-
----
- bacula/src/findlib/find.c | 2 --
- bacula/src/findlib/find.h | 1 -
- bacula/src/findlib/find_one.c | 41 +++++++++++++++++++++++++----------------
- 3 files changed, 25 insertions(+), 19 deletions(-)
-
-diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c
-index d089b70..38344f3 100644
---- a/bacula/src/findlib/find.c
-+++ b/bacula/src/findlib/find.c
-@@ -274,8 +274,6 @@ static bool accept_file(FF_PKT *ff)
- basename = ff->fname;
- }
-
-- ff->ignoredir = incexe->ignoredir;
--
- for (j = 0; j < incexe->opts_list.size(); j++) {
- findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
- ff->flags = fo->flags;
-diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h
-index ff9be47..707f529 100644
---- a/bacula/src/findlib/find.h
-+++ b/bacula/src/findlib/find.h
-@@ -215,7 +215,6 @@ struct FF_PKT {
- uint32_t flags; /* backup options */
- int GZIP_level; /* compression level */
- int strip_path; /* strip path count */
-- char *ignoredir; /* ignore directories with this file */
- bool cmd_plugin; /* set if we have a command plugin */
- alist fstypes; /* allowed file system types */
- alist drivetypes; /* allowed drive types */
-diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c
-index 5619ea4..f4f2e7b 100644
---- a/bacula/src/findlib/find_one.c
-+++ b/bacula/src/findlib/find_one.c
-@@ -299,6 +299,29 @@ static bool check_changes(JCR *jcr, FF_PKT *ff_pkt)
- return true;
- }
-
-+static bool have_ignoredir(FF_PKT *ff_pkt)
-+{
-+ struct stat sb;
-+ char tmp_name[MAXPATHLEN];
-+ char *ignoredir = ff_pkt->fileset->incexe->ignoredir;
-+
-+ if (ignoredir) {
-+ if (strlen(ff_pkt->fname) + strlen(ignoredir) + 2 > MAXPATHLEN) {
-+ return false;
-+ }
-+
-+ strcpy(tmp_name, ff_pkt->fname);
-+ strcat(tmp_name, "/");
-+ strcat(tmp_name, ignoredir);
-+ if (stat(tmp_name, &sb) == 0) {
-+ Dmsg2(100, "Directory '%s' ignored (found %s)\n",
-+ ff_pkt->fname, ignoredir);
-+ return true; /* Just ignore this directory */
-+ }
-+ }
-+ return false;
-+}
-+
- /*
- * Find a single file.
- * handle_file is the callback for handling the file.
-@@ -551,22 +574,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
- * Ignore this directory and everything below if the file .nobackup
- * (or what is defined for IgnoreDir in this fileset) exists
- */
-- if (ff_pkt->ignoredir != NULL) {
-- struct stat sb;
-- char fname[MAXPATHLEN];
--
-- if (strlen(ff_pkt->fname) + strlen("/") +
-- strlen(ff_pkt->ignoredir) + 1 > MAXPATHLEN)
-- return 1; /* Is this wisdom? */
--
-- strcpy(fname, ff_pkt->fname);
-- strcat(fname, "/");
-- strcat(fname, ff_pkt->ignoredir);
-- if (stat(fname, &sb) == 0) {
-- Dmsg2(100, "Directory '%s' ignored (found %s)\n",
-- ff_pkt->fname, ff_pkt->ignoredir);
-- return 1; /* Just ignore this directory */
-- }
-+ if (have_ignoredir(ff_pkt)) {
-+ return 1; /* Just ignore this directory */
- }
-
- /* Build a canonical directory name with a trailing slash in link var */
---
-1.6.3.1
-
+++ /dev/null
-From af393297b65456d07122f3e372ee3985dc747f06 Mon Sep 17 00:00:00 2001
-From: Eric Bollengier <eric@eb.homelinux.org>
-Date: Wed, 9 Sep 2009 10:24:20 +0200
-Subject: [PATCH] Fix #1369 about segfault when using ExcludeDirContaining before defining Options{} block.
-
----
- bacula/src/dird/dird_conf.c | 6 ++++++
- bacula/src/dird/dird_conf.h | 2 +-
- bacula/src/dird/fd_cmds.c | 6 +++---
- bacula/src/dird/inc_conf.c | 2 +-
- 4 files changed, 11 insertions(+), 5 deletions(-)
-
-diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c
-index d9995ad..0819e76 100644
---- a/bacula/src/dird/dird_conf.c
-+++ b/bacula/src/dird/dird_conf.c
-@@ -806,6 +806,9 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
- }
- sendit(sock, " N\n");
- }
-+ if (incexe->ignoredir) {
-+ sendit(sock, " Z %s\n", incexe->ignoredir);
-+ }
- for (j=0; j<incexe->name_list.size(); j++) {
- sendit(sock, " I %s\n", incexe->name_list.get(j));
- }
-@@ -1026,6 +1029,9 @@ static void free_incexe(INCEXE *incexe)
- if (incexe->opts_list) {
- free(incexe->opts_list);
- }
-+ if (incexe->ignoredir) {
-+ free(incexe->ignoredir);
-+ }
- free(incexe);
- }
-
-diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h
-index 231dfab..55706ec 100644
---- a/bacula/src/dird/dird_conf.h
-+++ b/bacula/src/dird/dird_conf.h
-@@ -462,7 +462,6 @@ struct FOPTS {
- alist drivetype; /* drive type limitation */
- char *reader; /* reader program */
- char *writer; /* writer program */
-- char *ignoredir; /* ignoredir string */
- char *plugin; /* plugin program */
- };
-
-@@ -474,6 +473,7 @@ struct INCEXE {
- int32_t num_opts; /* number of options items */
- alist name_list; /* filename list -- holds char * */
- alist plugin_list; /* filename list for plugins */
-+ char *ignoredir; /* ignoredir string */
- };
-
- /*
-diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c
-index 71d9fc3..2ef63d9 100644
---- a/bacula/src/dird/fd_cmds.c
-+++ b/bacula/src/dird/fd_cmds.c
-@@ -354,6 +354,9 @@ static bool send_fileset(JCR *jcr)
- ie = fileset->exclude_items[i];
- fd->fsend("E\n");
- }
-+ if (ie->ignoredir) {
-+ bnet_fsend(fd, "Z %s\n", ie->ignoredir);
-+ }
- for (j=0; j<ie->num_opts; j++) {
- FOPTS *fo = ie->opts_list[j];
- fd->fsend("O %s\n", fo->opts);
-@@ -399,9 +402,6 @@ static bool send_fileset(JCR *jcr)
- if (fo->plugin) {
- fd->fsend("G %s\n", fo->plugin);
- }
-- if (fo->ignoredir) {
-- bnet_fsend(fd, "Z %s\n", fo->ignoredir);
-- }
- if (fo->reader) {
- fd->fsend("D %s\n", fo->reader);
- }
-diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c
-index ef15d3f..aedde44 100644
---- a/bacula/src/dird/inc_conf.c
-+++ b/bacula/src/dird/inc_conf.c
-@@ -588,7 +588,7 @@ static void store_excludedir(LEX *lc, RES_ITEM2 *item, int index, int pass, bool
- }
- token = lex_get_token(lc, T_NAME);
- if (pass == 1) {
-- res_incexe.current_opts->ignoredir = bstrdup(lc->str);
-+ res_incexe.ignoredir = bstrdup(lc->str);
- }
- scan_to_eol(lc);
- }
---
-1.6.3.1
-
+++ /dev/null
- This patch can be applied to version 3.0.2 and fixes
- bug #1368 ASSERT Failure on MacOS. Unfortunately,
- MacOS programmers do not respect/implement POSIX
- pathconf().
-
- Apply it to version 3.0.2 with:
-
- cd <bacula-source>
- patch -p2 <3.0.2-mac-path-len.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c
-index ac9e4ce..81e887a 100644
---- a/bacula/src/findlib/find.c
-+++ b/bacula/src/findlib/find.c
-@@ -67,13 +67,13 @@ FF_PKT *init_find_files()
-
- /* Get system path and filename maximum lengths */
- path_max = pathconf(".", _PC_PATH_MAX);
-- if (path_max < 1024) {
-- path_max = 1024;
-+ if (path_max < 2048) {
-+ path_max = 2048;
- }
-
- name_max = pathconf(".", _PC_NAME_MAX);
-- if (name_max < 1024) {
-- name_max = 1024;
-+ if (name_max < 2048) {
-+ name_max = 2048;
- }
- path_max++; /* add for EOS */
- name_max++; /* add for EOS */
+++ /dev/null
-commit 6a6cba0ab43be4ba5572b408c3c4fb79352a5273
-Author: Eric Bollengier <eric@eb.homelinux.org>
-Date: Thu Sep 3 08:15:54 2009 +0200
-
- Fix #1364 and #1363 about compression buffer error.
-
-diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c
-index 808daec..a4ee03a 100644
---- a/bacula/src/filed/restore.c
-+++ b/bacula/src/filed/restore.c
-@@ -207,7 +207,7 @@ void do_restore(JCR *jcr)
-
- if (have_libz) {
- uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
-- jcr->compress_buf = (char *)bmalloc(compress_buf_size);
-+ jcr->compress_buf = get_memory(compress_buf_size);
- jcr->compress_buf_size = compress_buf_size;
- }
-
-@@ -802,7 +802,7 @@ ok_out:
- }
-
- if (jcr->compress_buf) {
-- free(jcr->compress_buf);
-+ free_pool_memory(jcr->compress_buf);
- jcr->compress_buf = NULL;
- jcr->compress_buf_size = 0;
- }
-@@ -1007,10 +1007,18 @@ bool decompress_data(JCR *jcr, char **data, uint32_t *length)
- */
- compress_len = jcr->compress_buf_size;
- Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
-- if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
-- (const Byte *)*data, (uLong)*length)) != Z_OK) {
-+ while ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
-+ (const Byte *)*data, (uLong)*length)) == Z_BUF_ERROR)
-+ {
-+ /* The buffer size is too small, try with a bigger one */
-+ compress_len = jcr->compress_buf_size = jcr->compress_buf_size + jcr->compress_buf_size >> 1;
-+ Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
-+ jcr->compress_buf = check_pool_memory_size(jcr->compress_buf,
-+ compress_len);
-+ }
-+ if (stat != Z_OK) {
- Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
-- jcr->last_fname, zlib_strerror(stat));
-+ jcr->last_fname, zlib_strerror(stat));
- return false;
- }
- *data = jcr->compress_buf;
-diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c
-index 1a8c67f..5786a4c 100644
---- a/bacula/src/stored/bextract.c
-+++ b/bacula/src/stored/bextract.c
-@@ -438,9 +438,16 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
- wbuf = rec->data;
- wsize = rec->data_len;
- }
-- compress_len = compress_buf_size;
-- if ((stat=uncompress((Bytef *)compress_buf, &compress_len,
-- (const Bytef *)wbuf, (uLong)wsize) != Z_OK)) {
-+
-+ while ((stat=uncompress((Byte *)compress_buf, &compress_len,
-+ (const Byte *)wbuf, (uLong)wsize)) == Z_BUF_ERROR)
-+ {
-+ /* The buffer size is too small, try with a bigger one */
-+ compress_len = compress_len + compress_len >> 1;
-+ compress_buf = check_pool_memory_size(compress_buf,
-+ compress_len);
-+ }
-+ if (stat != Z_OK) {
- Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
- extract = false;
- return true;
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and makes
+ error conditions obtaining acls during backup non-fatal.
+ This should fix bug #1305.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-acl-error.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/filed/acl.c
+===================================================================
+--- src/filed/acl.c (revision 8902)
++++ src/filed/acl.c (working copy)
+@@ -406,31 +406,35 @@
+ pm_strcpy(jcr->acl_data, "");
+ acl_free(acl);
+
+- return -1;
++ return 0; /* non-fatal error */
+ }
+
+ /*
+ * Handle errors gracefully.
+ */
+- switch (errno) {
++ if (acl == (acl_t)NULL) {
++ switch (errno) {
+ #if defined(BACL_ENOTSUP)
+- case BACL_ENOTSUP:
+- /*
+- * Not supported, just pretend there is nothing to see
+- */
+- pm_strcpy(jcr->acl_data, "");
+- return 0;
++ case BACL_ENOTSUP:
++ break; /* not supported */
+ #endif
+- default:
+- berrno be;
+- Jmsg2(jcr, M_ERROR, 0, _("acl_get_file error on file \"%s\": ERR=%s\n"),
+- jcr->last_fname, be.bstrerror());
+- Dmsg2(100, "acl_get_file error file=%s ERR=%s\n",
+- jcr->last_fname, be.bstrerror());
++ default:
++ berrno be;
++ /* Some real error */
++ Jmsg2(jcr, M_ERROR, 0, _("acl_get_file error on file \"%s\": ERR=%s\n"),
++ jcr->last_fname, be.bstrerror());
++ Dmsg2(100, "acl_get_file error file=%s ERR=%s\n",
++ jcr->last_fname, be.bstrerror());
+
+- pm_strcpy(jcr->acl_data, "");
+- return -1;
++ pm_strcpy(jcr->acl_data, "");
++ return 0; /* non-fatal error */
++ }
+ }
++ /*
++ * Not supported, just pretend there is nothing to see
++ */
++ pm_strcpy(jcr->acl_data, "");
++ return 0;
+ }
+
+ /*
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and should
+ fix bug #1309 btape fill multiple tape generates error but
+ end of fill test says successful.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-btape.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/stored/btape.c
+===================================================================
+--- src/stored/btape.c (revision 8902)
++++ src/stored/btape.c (working copy)
+@@ -414,7 +414,6 @@
+ }
+ }
+ dev->rewind(dcr);
+- dev->weof(1);
+ write_new_volume_label_to_dev(dcr, cmd, "Default", false,/*no relabel*/ true /* label dvd now */);
+ Pmsg1(-1, _("Wrote Volume label for volume \"%s\".\n"), cmd);
+ }
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and should fix
+ a crash in the SD that occurs after canceling a job.
+ This should fix bug #1298.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-cancel-sd.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/stored/reserve.c
+===================================================================
+--- src/stored/reserve.c (revision 8892)
++++ src/stored/reserve.c (working copy)
+@@ -755,6 +755,9 @@
+ bool ok = false;
+
+ ASSERT(dcr);
++ if (job_canceled(jcr)) {
++ return false;
++ }
+
+ dev->dlock();
+
+@@ -809,6 +812,9 @@
+ bool ok = false;
+
+ ASSERT(dcr);
++ if (job_canceled(jcr)) {
++ return false;
++ }
+
+ dev->dlock();
+
+Index: src/stored/spool.c
+===================================================================
+--- src/stored/spool.c (revision 8892)
++++ src/stored/spool.c (working copy)
+@@ -436,6 +436,9 @@
+ bool despool = false;
+ DEV_BLOCK *block = dcr->block;
+
++ if (job_canceled(dcr->jcr)) {
++ return false;
++ }
+ ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
+ if (block->binbuf <= WRITE_BLKHDR_LENGTH) { /* Does block have data in it? */
+ return true;
+Index: src/stored/vol_mgr.c
+===================================================================
+--- src/stored/vol_mgr.c (revision 8892)
++++ src/stored/vol_mgr.c (working copy)
+@@ -344,6 +344,9 @@
+ VOLRES *vol, *nvol;
+ DEVICE * volatile dev = dcr->dev;
+
++ if (job_canceled(dcr->jcr)) {
++ return NULL;
++ }
+ ASSERT(dev != NULL);
+
+ Dmsg2(dbglvl, "enter reserve_volume=%s drive=%s\n", VolumeName,
+@@ -701,6 +704,9 @@
+ bool rtn = true;
+ VOLRES *vol;
+
++ if (job_canceled(jcr)) {
++ return false;
++ }
+ lock_volumes();
+ vol = find_volume(VolumeName);
+ if (!vol) {
+Index: src/stored/askdir.c
+===================================================================
+--- src/stored/askdir.c (revision 8892)
++++ src/stored/askdir.c (working copy)
+@@ -494,6 +494,9 @@
+ JCR *jcr = dcr->jcr;
+ bool got_vol = false;
+
++ if (job_canceled(jcr)) {
++ return false;
++ }
+ Dmsg0(400, "enter dir_ask_sysop_to_create_appendable_volume\n");
+ ASSERT(dev->blocked());
+ for ( ;; ) {
+Index: src/stored/block.c
+===================================================================
+--- src/stored/block.c (revision 8892)
++++ src/stored/block.c (working copy)
+@@ -415,6 +415,9 @@
+ empty_block(block);
+ return true;
+ #endif
++ if (job_canceled(jcr)) {
++ return false;
++ }
+ ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
+ ASSERT(dev->is_open());
+
+@@ -935,6 +938,9 @@
+ DEVICE *dev = dcr->dev;
+ DEV_BLOCK *block = dcr->block;
+
++ if (job_canceled(jcr)) {
++ return false;
++ }
+ ASSERT(dev->is_open());
+
+ if (dev->at_eot()) {
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and should
+ fix bug #1307 where a Job being escalated with
+ Allow Higher Duplicates = no is cancelled.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-higher-duplicates.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/dird/job.c
+===================================================================
+--- src/dird/job.c (revision 8902)
++++ src/dird/job.c (working copy)
+@@ -672,6 +672,9 @@
+ if (!job->AllowHigherDuplicates) {
+ foreach_jcr(djcr) {
+ char ec1[50];
++ if (jcr == djcr) {
++ continue; /* do not cancel this job */
++ }
+ if (strcmp(job->name(), djcr->job->name()) == 0) {
+ bool cancel_queued = false;
+ if (job->DuplicateJobProximity > 0) {
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and fixes a
+ IP address resolution priorities between ipv4 and ipv6.
+ This should fix bug #1029
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-ipv6-resolution-order.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+Index: src/lib/bnet.c
+===================================================================
+--- src/lib/bnet.c (révision 8841)
++++ src/lib/bnet.c (copie de travail)
+@@ -495,13 +495,16 @@
+ return 0;
+ }
+ } else {
+- errmsg = resolv_host(AF_INET, host, addr_list);
+ #ifdef HAVE_IPV6
+- if (errmsg) {
+- errmsg = resolv_host(AF_INET6, host, addr_list);
+- }
++ /* We try to resolv host for ipv6 and ipv4, the connection procedure
++ * will try to reach the host for each protocols. We report only "Host
++ * not found" ipv4 message (no need to have ipv6 and ipv4 messages).
++ */
++ resolv_host(AF_INET6, host, addr_list);
+ #endif
+- if (errmsg) {
++ errmsg = resolv_host(AF_INET, host, addr_list);
++
++ if (addr_list->size() == 0) {
+ *errstr = errmsg;
+ free_addresses(addr_list);
+ return 0;
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and ensures that
+ if maxdiffinterval is set, it will be done even if no prior
+ Diff job ran. This should fix bug #1311.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-maxdiff.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/dird/fd_cmds.c
+===================================================================
+--- src/dird/fd_cmds.c (revision 8911)
++++ src/dird/fd_cmds.c (working copy)
+@@ -198,22 +198,33 @@
+ now = (utime_t)time(NULL);
+ jcr->jr.JobId = 0; /* flag to return since time */
+ have_full = db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime);
+- /* If there was a successful job, make sure it is recent enough */
+- if (jcr->get_JobLevel() == L_INCREMENTAL && have_full && jcr->job->MaxDiffInterval > 0) {
++ if (have_full) {
++ last_full_time = str_to_utime(jcr->stime);
++ } else {
++ do_full = true; /* No full, upgrade to one */
++ }
++ /* Make sure the last diff is recent enough */
++ if (have_full && jcr->get_JobLevel() == L_INCREMENTAL && jcr->job->MaxDiffInterval > 0) {
+ /* Lookup last diff job */
+ if (db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, L_DIFFERENTIAL)) {
+ last_diff_time = str_to_utime(stime);
+- do_diff = ((now - last_diff_time) >= jcr->job->MaxDiffInterval);
++ /* If no Diff since Full, use Full time */
++ if (last_diff_time < last_full_time) {
++ last_diff_time = last_full_time;
++ }
++ } else {
++ /* No last differential, so use last full time */
++ last_diff_time = last_full_time;
+ }
++ do_diff = ((now - last_diff_time) >= jcr->job->MaxDiffInterval);
+ }
+- if (have_full && jcr->job->MaxFullInterval > 0 &&
+- db_find_last_job_start_time(jcr, jcr->db, &jcr->jr, &stime, L_FULL)) {
+- last_full_time = str_to_utime(stime);
++ /* Note, do_full takes precedence over do_diff */
++ if (have_full && jcr->job->MaxFullInterval > 0) {
+ do_full = ((now - last_full_time) >= jcr->job->MaxFullInterval);
+ }
+ free_pool_memory(stime);
+
+- if (!have_full || do_full) {
++ if (do_full) {
+ /* No recent Full job found, so upgrade this one to Full */
+ Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db));
+ Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing FULL backup.\n"));
+@@ -221,7 +232,7 @@
+ level_to_str(jcr->get_JobLevel()));
+ jcr->set_JobLevel(jcr->jr.JobLevel = L_FULL);
+ } else if (do_diff) {
+- /* No recent diff job found, so upgrade this one to Full */
++ /* No recent diff job found, so upgrade this one to Diff */
+ Jmsg(jcr, M_INFO, 0, _("No prior or suitable Differential backup found in catalog. Doing Differential backup.\n"));
+ bsnprintf(since, since_len, _(" (upgraded from %s)"),
+ level_to_str(jcr->get_JobLevel()));
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and should improve
+ error messages when a migration sql query is used and correct
+ the problem identified in bug #1303 with starting Job names
+ containing spaces.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-migrate-sql.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/dird/migrate.c
+===================================================================
+--- src/dird/migrate.c (revision 8887)
++++ src/dird/migrate.c (working copy)
+@@ -481,6 +481,12 @@
+ {
+ idpkt *ids = (idpkt *)ctx;
+
++ /* Sanity check */
++ if (!row || !row[0]) {
++ Dmsg0(dbglevel, "dbid_hdlr error empty row\n");
++ return 1; /* stop calling us */
++ }
++
+ add_unique_id(ids, row[0]);
+ Dmsg3(dbglevel, "dbid_hdlr count=%d Ids=%p %s\n", ids->count, ids->list, ids->list);
+ return 0;
+@@ -847,9 +853,6 @@
+ JobId = 0;
+ stat = get_next_jobid_from_list(&p, &JobId);
+ Dmsg3(dbglevel, "get_jobid_no=%d stat=%d JobId=%u\n", i, stat, JobId);
+- jcr->MigrateJobId = JobId;
+- start_migration_job(jcr);
+- Dmsg0(dbglevel, "Back from start_migration_job\n");
+ if (stat < 0) {
+ Jmsg(jcr, M_FATAL, 0, _("Invalid JobId found.\n"));
+ goto bail_out;
+@@ -857,6 +860,9 @@
+ Jmsg(jcr, M_INFO, 0, _("No JobIds found to %s.\n"), jcr->get_ActionName(0));
+ goto ok_out;
+ }
++ jcr->MigrateJobId = JobId;
++ start_migration_job(jcr);
++ Dmsg0(dbglevel, "Back from start_migration_job\n");
+ }
+
+ /* Now get the last JobId and handle it in the current job */
+@@ -908,7 +914,7 @@
+ UAContext *ua = new_ua_context(jcr);
+ char ed1[50];
+ ua->batch = true;
+- Mmsg(ua->cmd, "run %s jobid=%s", jcr->job->hdr.name,
++ Mmsg(ua->cmd, "run job=\"%s\" jobid=%s", jcr->job->name(),
+ edit_uint64(jcr->MigrateJobId, ed1));
+ Dmsg2(dbglevel, "=============== %s cmd=%s\n", jcr->get_OperationName(), ua->cmd);
+ parse_ua_args(ua); /* parse command */
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and fixes a
+ a race condition that causes the SD to hang. This should
+ fix bug #1287.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-sd-hang.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/lib/jcr.c
+===================================================================
+--- src/lib/jcr.c (revision 8840)
++++ src/lib/jcr.c (working copy)
+@@ -518,6 +518,7 @@
+ jcr->JobId, jcr->use_count(), jcr->Job);
+ }
+ remove_jcr(jcr); /* remove Jcr from chain */
++ unlock_jcr_chain();
+
+ dequeue_messages(jcr);
+ job_end_pop(jcr); /* pop and call hooked routines */
+@@ -571,7 +572,6 @@
+ jcr->daemon_free_jcr(jcr); /* call daemon free routine */
+ }
+
+- unlock_jcr_chain();
+ free_common_jcr(jcr);
+ close_msg(NULL); /* flush any daemon messages */
+ garbage_collect_memory_pool();
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and fixes a
+ syntax error that causes builds on older Solarises to fail.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-solaris-acl.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+Index: src/filed/acl.c
+===================================================================
+--- src/filed/acl.c (revision 8810)
++++ src/filed/acl.c (working copy)
+@@ -1141,7 +1141,7 @@
+ /*
+ * OS specific functions for handling different types of acl streams.
+ */
+-static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt);
++static bool solaris_build_acl_streams(JCR *jcr, FF_PKT *ff_pkt)
+ {
+ int n;
+ aclent_t *acls;
--- /dev/null
+
+ This patch can be applied to version 3.0.1 and modifies xattr
+ handling to print warning or error messages when problems are
+ found without canceling the Job. This patch *must* be applied
+ after 3.0.1-acl-error.patch. It should fix the re-opened
+ bug #1305.
+
+ Apply it to version 3.0.1 with:
+
+ cd <bacula-source>
+ patch -p0 <3.0.1-xattr.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+Index: src/filed/xattr.c
+===================================================================
+--- src/filed/xattr.c (revision 8923)
++++ src/filed/xattr.c (working copy)
+@@ -96,7 +96,6 @@
+ if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ sd->bstrerror());
+-
+ return false;
+ }
+
+@@ -112,7 +111,6 @@
+ sd->msglen = 0;
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ sd->bstrerror());
+-
+ return false;
+ }
+
+@@ -121,10 +119,8 @@
+ if (!sd->signal(BNET_EOD)) {
+ Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+ sd->bstrerror());
+-
+ return false;
+ }
+-
+ Dmsg1(200, "XATTR of file: %s successfully backed up!\n", jcr->last_fname);
+
+ return true;
+@@ -265,8 +261,7 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+- return false;
++ return true; /* non-fatal return */
+ } else if (xattr_list_len == 0) {
+ return true;
+ }
+@@ -274,11 +269,7 @@
+ /*
+ * Allocate room for the extented attribute list.
+ */
+- if ((xattr_list = (char *)malloc(xattr_list_len + 1)) == (char *)NULL) {
+- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_list_len + 1);
+-
+- return false;
+- }
++ xattr_list = (char *)malloc(xattr_list_len + 1);
+ memset((caddr_t)xattr_list, 0, xattr_list_len + 1);
+
+ /*
+@@ -291,10 +282,8 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+ free(xattr_list);
+-
+- return false;
++ return true; /* non-fatal return */
+ }
+ xattr_list[xattr_list_len] = '\0';
+
+@@ -328,11 +317,7 @@
+ * Allocate enough room to hold all extended attributes.
+ * After allocating the storage make sure its empty by zeroing it.
+ */
+- if ((xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t))) == (xattr_t *)NULL) {
+- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), count * sizeof(xattr_t));
+-
+- return false;
+- }
++ xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t));
+ memset((caddr_t)xattr_value_list, 0, count * sizeof(xattr_t));
+
+ /*
+@@ -345,7 +330,6 @@
+ #if defined(HAVE_LINUX_OS)
+ if (ff_pkt->flags & FO_ACL && !strcmp(bp, "system.posix_acl_access")) {
+ bp = strchr(bp, '\0') + 1;
+-
+ continue;
+ }
+ #endif
+@@ -360,11 +344,7 @@
+ * Allocate space for storing the name.
+ */
+ current_xattr->name_length = strlen(bp);
+- if ((current_xattr->name = (char *)malloc(current_xattr->name_length)) == (char *)NULL) {
+- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr->name_length);
+-
+- goto bail_out;
+- }
++ current_xattr->name = (char *)malloc(current_xattr->name_length);
+ memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length);
+
+ expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length;
+@@ -379,18 +359,13 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+ goto bail_out;
+ }
+
+ /*
+ * Allocate space for storing the value.
+ */
+- if ((current_xattr->value = (char *)malloc(xattr_value_len)) == (char *)NULL) {
+- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_value_len);
+-
+- goto bail_out;
+- }
++ current_xattr->value = (char *)malloc(xattr_value_len);
+ memset((caddr_t)current_xattr->value, 0, xattr_value_len);
+
+ xattr_value_len = lgetxattr(jcr->last_fname, bp, current_xattr->value, xattr_value_len);
+@@ -400,7 +375,6 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+ goto bail_out;
+ }
+
+@@ -416,7 +390,6 @@
+ if (expected_serialize_len >= MAX_XATTR_STREAM) {
+ Jmsg2(jcr, M_ERROR, 0, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
+ jcr->last_fname, MAX_XATTR_STREAM);
+-
+ goto bail_out;
+ }
+
+@@ -435,7 +408,6 @@
+ jcr->last_fname);
+ Dmsg1(100, "Failed to serialize extended attributes on file \"%s\"\n",
+ jcr->last_fname);
+-
+ goto bail_out;
+ }
+
+@@ -450,15 +422,14 @@
+ bail_out:
+ xattr_drop_internal_table(xattr_value_list);
+ free(xattr_list);
+-
+- return false;
++ return true; /* non-fatal return */
+ }
+
+ static bool generic_xattr_parse_streams(JCR *jcr)
+ {
+ unser_declare;
+ xattr_t current_xattr;
+- bool retval = true;
++ bool retval = true; /* default non-fatal */
+
+ /*
+ * Parse the stream and perform the setxattr calls on the file.
+@@ -478,8 +449,7 @@
+ jcr->last_fname);
+ Dmsg1(100, "Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n",
+ jcr->last_fname);
+-
+- return false;
++ return true; /* non-fatal return */
+ }
+
+ /*
+@@ -490,11 +460,7 @@
+ /*
+ * Allocate room for the name and decode its content.
+ */
+- if ((current_xattr.name = (char *)malloc(current_xattr.name_length + 1)) == (char *)NULL) {
+- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.name_length + 1);
+-
+- return false;
+- }
++ current_xattr.name = (char *)malloc(current_xattr.name_length + 1);
+ unser_bytes(current_xattr.name, current_xattr.name_length);
+
+ /*
+@@ -510,11 +476,7 @@
+ /*
+ * Allocate room for the value and decode its content.
+ */
+- if ((current_xattr.value = (char *)malloc(current_xattr.value_length)) == (char *)NULL) {
+- Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.value_length);
+-
+- return false;
+- }
++ current_xattr.value = (char *)malloc(current_xattr.value_length);
+ unser_bytes(current_xattr.value, current_xattr.value_length);
+
+ /*
+@@ -529,12 +491,6 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "lsetxattr error file=%s ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+- /*
+- * Reset the return flag to false to indicate one or more extended attributes
+- * could not be restored.
+- */
+- retval = false;
+ }
+
+ /*
+@@ -560,7 +516,10 @@
+ case STREAM_XATTR_DARWIN:
+ return generic_xattr_parse_streams(jcr);
+ default:
+- return false;
++ Jmsg2(jcr, M_WARNING, 0,
++ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
++ jcr->last_fname, stream);
++ return true; /* non-fatal error */
+ }
+ }
+ #elif defined(HAVE_FREEBSD_OS)
+@@ -575,7 +534,10 @@
+ case STREAM_XATTR_FREEBSD:
+ return generic_xattr_parse_streams(jcr);
+ default:
+- return false;
++ Jmsg2(jcr, M_WARNING, 0,
++ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
++ jcr->last_fname, stream);
++ return true; /* non-fatal error */
+ }
+ }
+ #elif defined(HAVE_LINUX_OS)
+@@ -590,7 +552,10 @@
+ case STREAM_XATTR_LINUX:
+ return generic_xattr_parse_streams(jcr);
+ default:
+- return false;
++ Jmsg2(jcr, M_WARNING, 0,
++ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
++ jcr->last_fname, stream);
++ return true; /* non-fatal error */
+ }
+ }
+ #elif defined(HAVE_NETBSD_OS)
+@@ -605,7 +570,10 @@
+ case STREAM_XATTR_NETBSD:
+ return generic_xattr_parse_streams(jcr);
+ default:
+- return false;
++ Jmsg2(jcr, M_WARNING, 0,
++ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
++ jcr->last_fname, stream);
++ return true; /* non-fatal error */
+ }
+ }
+ #endif
+@@ -726,10 +694,11 @@
+ {
+ xattr_link_cache_entry_t *ptr;
+
+- for (ptr = xattr_link_cache_head; ptr != NULL; ptr = ptr->next)
+- if (ptr->inum == inum)
++ for (ptr = xattr_link_cache_head; ptr != NULL; ptr = ptr->next) {
++ if (ptr->inum == inum) {
+ return ptr;
+-
++ }
++ }
+ return NULL;
+ }
+
+@@ -737,16 +706,16 @@
+ {
+ xattr_link_cache_entry_t *ptr;
+
+- if ((ptr = (xattr_link_cache_entry_t *)malloc(sizeof(struct xattr_link_cache_entry))) != NULL) {
+- memset((caddr_t)ptr, 0, sizeof(struct xattr_link_cache_entry));
+- ptr->inum = inum;
+- strncpy(ptr->target, target, sizeof(ptr->target));
+- if (xattr_link_cache_head == NULL)
+- xattr_link_cache_head = ptr;
+- if (xattr_link_cache_tail != NULL)
+- xattr_link_cache_tail->next = ptr;
+- xattr_link_cache_tail = ptr;
++ ptr = (xattr_link_cache_entry_t *)malloc(sizeof(struct xattr_link_cache_entry));
++ memset((caddr_t)ptr, 0, sizeof(struct xattr_link_cache_entry));
++ ptr->inum = inum;
++ strncpy(ptr->target, target, sizeof(ptr->target));
++ if (xattr_link_cache_head == NULL) {
++ xattr_link_cache_head = ptr;
+ }
++ if (xattr_link_cache_tail != NULL)
++ xattr_link_cache_tail->next = ptr;
++ }
+ }
+
+ static void drop_xattr_link_cache(void)
+@@ -757,7 +726,6 @@
+ next = ptr->next;
+ free(ptr);
+ }
+-
+ xattr_link_cache_head = NULL;
+ xattr_link_cache_tail = NULL;
+ }
+@@ -828,9 +796,9 @@
+ }
+
+ cleanup:
+- if (response != NULL)
++ if (response != NULL) {
+ nvlist_free(response);
+-
++ }
+ return retval;
+ }
+ #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
+@@ -847,19 +815,17 @@
+
+ for (n = 0; n < count; n++) {
+ ace = &entries[n];
+-
+ if (!(ace->a_type == USER_OBJ ||
+ ace->a_type == GROUP_OBJ ||
+ ace->a_type == OTHER_OBJ ||
+ ace->a_type == CLASS_OBJ))
+ return false;
+ }
+-
+ return true;
+ }
+ #endif /* HAVE_ACL && !HAVE_EXTENDED_ACL */
+
+-static bool solaris_archive_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
++static bool solaris_save_xattr_acl(JCR *jcr, int fd, const char *attrname, char **acl_text)
+ {
+ #ifdef HAVE_ACL
+ #ifdef HAVE_EXTENDED_ACL
+@@ -881,8 +847,7 @@
+ attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "facl_get/acl_get of xattr %s on \"%s\" failed: ERR=%s\n",
+ attrname, jcr->last_fname, be.bstrerror());
+-
+- return false;
++ return true; /* non-fatal */
+ }
+
+ if (aclp != NULL) {
+@@ -912,10 +877,11 @@
+ /*
+ * See if this attribute has an ACL
+ */
+- if (fd != -1)
++ if (fd != -1) {
+ n = facl(fd, GETACLCNT, 0, NULL);
+- else
++ } else {
+ n = acl(attrname, GETACLCNT, 0, NULL);
++ }
+
+ if (n >= MIN_ACL_ENTRIES) {
+ acls = (aclent_t *)malloc(n * sizeof(aclent_t));
+@@ -926,9 +892,8 @@
+ attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "facl/acl of xattr %s on \"%s\" failed: ERR=%s\n",
+ attrname, jcr->last_fname, be.bstrerror());
+-
+ free(acls);
+- return false;
++ return true; /* non-fatal */
+ }
+
+ /*
+@@ -941,9 +906,8 @@
+ attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "acltotext of xattr %s on \"%s\" failed: ERR=%s\n",
+ attrname, jcr->last_fname, be.bstrerror());
+-
+ free(acls);
+- return false;
++ return true; /* non-fatal */
+ }
+ } else {
+ *acl_text = NULL;
+@@ -956,18 +920,19 @@
+
+ return true;
+ #endif /* HAVE_EXTENDED_ACL */
++
+ #else /* HAVE_ACL */
+- return NULL;
++ return false; /* fatal return */
+ #endif /* HAVE_ACL */
+ }
+
+ /*
+ * Forward declaration for recursive function call.
+ */
+-static bool solaris_archive_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
++static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent);
+
+ /*
+- * Archive an extended or extensible attribute.
++ * Save an extended or extensible attribute.
+ * This is stored as an opaque stream of bytes with the following encoding:
+ *
+ * <xattr_name>\0<stat_buffer>\0<acl_string>\0<actual_xattr_data>
+@@ -981,7 +946,7 @@
+ * acl_string is an acl text when a non trivial acl is set on the xattr.
+ * actual_xattr_data is the content of the xattr file.
+ */
+-static bool solaris_archive_xattr(JCR *jcr, int fd, const char *xattr_namespace,
++static bool solaris_save_xattr(JCR *jcr, int fd, const char *xattr_namespace,
+ const char *attrname, bool toplevel_hidden_dir, int stream)
+ {
+ int cnt;
+@@ -993,7 +958,7 @@
+ char *acl_text = NULL;
+ char attribs[MAXSTRING];
+ char buffer[BUFSIZ];
+- bool retval = false;
++ bool retval = true; /* default is non-fatal */
+
+ snprintf(target_attrname, sizeof(target_attrname), "%s%s", xattr_namespace, attrname);
+
+@@ -1006,7 +971,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "fstatat of xattr %s on \"%s\" failed: ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1022,7 +986,7 @@
+ /*
+ * Get any acl on the xattr.
+ */
+- if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
++ if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
+ goto cleanup;
+
+ /*
+@@ -1033,15 +997,16 @@
+ cnt = snprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c",
+ target_attrname, 0, attribs, 0, (acl_text) ? acl_text : "", 0);
+ break;
++
+ case S_IFDIR:
+ /*
+ * Get any acl on the xattr.
+ */
+- if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
++ if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text))
+ goto cleanup;
+
+ /*
+- * See if this is the toplevel_hidden_dir being archived.
++ * See if this is the toplevel_hidden_dir being saved.
+ */
+ if (toplevel_hidden_dir) {
+ /*
+@@ -1054,7 +1019,6 @@
+ "%s%c%s%c%s%c",
+ target_attrname, 0, attribs, 0,
+ (acl_text) ? acl_text : "", 0);
+-
+ goto cleanup;
+ } else {
+ /*
+@@ -1088,7 +1052,7 @@
+ retval = send_xattr_stream(jcr, stream);
+
+ /*
+- * For a hard linked file we are ready now, no need to recursively archive the attributes.
++ * For a hard linked file we are ready now, no need to recursively save the attributes.
+ */
+ goto cleanup;
+ }
+@@ -1103,8 +1067,9 @@
+ /*
+ * Get any acl on the xattr.
+ */
+- if (!solaris_archive_xattr_acl(jcr, attrfd, attrname, &acl_text))
++ if (!solaris_save_xattr_acl(jcr, attrfd, attrname, &acl_text)) {
+ goto cleanup;
++ }
+
+ /*
+ * Encode the stat struct into an ASCII representation.
+@@ -1123,10 +1088,10 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "openat of xattr %s on \"%s\" failed: ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+ break;
++
+ case S_IFLNK:
+ /*
+ * The current implementation of xattr on Solaris doesn't support this, but if it ever does we are prepared.
+@@ -1138,7 +1103,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "readlink of xattr %s on \"%s\" failed: ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1154,9 +1118,10 @@
+ retval = send_xattr_stream(jcr, stream);
+
+ /*
+- * For a soft linked file we are ready now, no need to recursively archive the attributes.
++ * For a soft linked file we are ready now, no need to recursively save the attributes.
+ */
+ goto cleanup;
++
+ default:
+ goto cleanup;
+ }
+@@ -1167,7 +1132,7 @@
+ if (nr_xattr_saved == 0) {
+ pm_memcpy(jcr->xattr_data, toplevel_hidden_dir_xattr_data, toplevel_hidden_dir_xattr_data_len);
+ jcr->xattr_data_len = toplevel_hidden_dir_xattr_data_len;
+- send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
++ retval = send_xattr_stream(jcr, STREAM_XATTR_SOLARIS);
+ }
+
+ pm_memcpy(jcr->xattr_data, buffer, cnt);
+@@ -1185,7 +1150,6 @@
+ if (st.st_size >= MAX_XATTR_STREAM) {
+ Jmsg2(jcr, M_ERROR, 0, _("Xattr stream on file \"%s\" exceeds maximum size of %d bytes\n"),
+ jcr->last_fname, MAX_XATTR_STREAM);
+-
+ goto cleanup;
+ }
+
+@@ -1200,24 +1164,26 @@
+ target_attrname, jcr->last_fname);
+ Dmsg2(100, "read of data from xattr %s on \"%s\" failed\n",
+ target_attrname, jcr->last_fname);
+-
+ goto cleanup;
+ }
+ }
+ break;
++
+ default:
+ break;
+ }
+
+- retval = send_xattr_stream(jcr, stream);
+- nr_xattr_saved++;
++ if (retval) {
++ retval = send_xattr_stream(jcr, stream);
++ nr_xattr_saved++;
++ }
+
+ /*
+- * Recursivly call solaris_archive_extended_attributes for archiving the attributes
++ * Recursivly call solaris_save_extended_attributes for archiving the attributes
+ * available on this extended attribute.
+ */
+ if (retval) {
+- retval = solaris_archive_xattrs(jcr, xattr_namespace, attrname);
++ retval = solaris_save_xattrs(jcr, xattr_namespace, attrname);
+
+ /*
+ * The recursive call could change our working dir so change back to the wanted workdir.
+@@ -1228,28 +1194,28 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to fchdir to xattr space of file \"%s\" using fd %d: ERR=%s\n",
+ jcr->last_fname, fd, be.bstrerror());
+-
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+- if (acl_text)
++ if (acl_text) {
+ free(acl_text);
+- if (attrfd != -1)
++ }
++ if (attrfd != -1) {
+ close(attrfd);
+-
++ }
+ return retval;
+ }
+
+-static bool solaris_archive_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
++static bool solaris_save_xattrs(JCR *jcr, const char *xattr_namespace, const char *attr_parent)
+ {
+ const char *name;
+ int fd, filefd = -1, attrdirfd = -1;
+ DIR *dirp;
+ struct dirent *dp;
+ char current_xattr_namespace[PATH_MAX];
+- bool retval = false;
++ bool retval = true; /* default non-fatal error */
+
+ /*
+ * Determine what argument to use. Use attr_parent when set
+@@ -1258,18 +1224,19 @@
+ */
+ if (attr_parent) {
+ name = attr_parent;
+- if (xattr_namespace)
++ if (xattr_namespace) {
+ snprintf(current_xattr_namespace, sizeof(current_xattr_namespace), "%s%s/",
+ xattr_namespace, attr_parent);
+- else
+- strcpy(current_xattr_namespace, "/");
++ } else {
++ strncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
++ }
+ } else {
+ name = jcr->last_fname;
+- strcpy(current_xattr_namespace, "/");
++ strncpy(current_xattr_namespace, "/", sizeof(current_xattr_namespace));
+ }
+
+ /*
+- * Open the file on which to archive the xattrs read-only.
++ * Open the file on which to save the xattrs read-only.
+ */
+ if ((filefd = open(name, O_RDONLY | O_NONBLOCK)) < 0) {
+ berrno be;
+@@ -1277,7 +1244,6 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1301,13 +1267,12 @@
+ Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
+ name, jcr->last_fname, be.bstrerror());
+ }
+-
+ goto cleanup;
+ }
+
+ /*
+ * We need to change into the attribute directory to determine if each of the
+- * attributes should be archived.
++ * attributes should be saved.
+ */
+ if (fchdir(attrdirfd) < 0) {
+ berrno be;
+@@ -1315,7 +1280,6 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
+ jcr->last_fname, attrdirfd, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1325,7 +1289,7 @@
+ * And as we want this entry before anything else we better just save its data.
+ */
+ if (!attr_parent)
+- solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, ".",
++ solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, ".",
+ true, STREAM_XATTR_SOLARIS);
+
+ if ((fd = dup(attrdirfd)) == -1 ||
+@@ -1381,23 +1345,22 @@
+ if (!solaris_has_non_transient_extensible_attributes(filefd)) {
+ Dmsg3(400, "Skipping transient extensible attributes %s%s on file \"%s\"\n",
+ current_xattr_namespace, dp->d_name, jcr->last_fname);
+-
+ continue;
+ }
+
+ /*
+- * Archive the xattr.
++ * Save the xattr.
+ */
+- solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
++ solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
+ false, STREAM_XATTR_SOLARIS_SYS);
+ continue;
+ }
+ #endif /* HAVE_SYS_NVPAIR_H && _PC_SATTR_ENABLED */
+
+ /*
+- * Archive the xattr.
++ * Save the xattr.
+ */
+- solaris_archive_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
++ solaris_save_xattr(jcr, attrdirfd, current_xattr_namespace, dp->d_name,
+ false, STREAM_XATTR_SOLARIS);
+ }
+
+@@ -1409,7 +1372,6 @@
+ close(attrdirfd);
+ if (filefd != -1)
+ close(filefd);
+-
+ return retval;
+ }
+
+@@ -1421,7 +1383,9 @@
+ acl_t *aclp = NULL;
+
+ if ((error = acl_fromtext(acl_text, &aclp)) != 0) {
+- return false;
++ Jmsg1(jcr, M_ERROR, 0, _("Unable to convert acl from text on file \"%s\"\n"
++ jcr->last_fname));
++ return true; /* non-fatal */
+ }
+
+ if ((fd != -1 && facl_set(fd, aclp) != 0) ||
+@@ -1431,14 +1395,14 @@
+ attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
+ attrname, jcr->last_fname, be.bstrerror());
+-
+- return false;
++ return true; /* non-fatal */
+ }
+
+- if (aclp)
++ if (aclp) {
+ acl_free(aclp);
+-
++ }
+ return true;
++
+ #else /* HAVE_EXTENDED_ACL */
+ int n;
+ aclent_t *acls = NULL;
+@@ -1452,16 +1416,17 @@
+ attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to restore acl of xattr %s on file \"%s\": ERR=%s\n",
+ attrname, jcr->last_fname, be.bstrerror());
+-
+- return false;
++ return true; /* non-fatal */
+ }
+ }
+
+- if (acls)
++ if (acls) {
+ free(acls);
+-
++ }
+ return true;
++
+ #endif /* HAVE_EXTENDED_ACL */
++
+ }
+ #endif /* HAVE_ACL */
+
+@@ -1476,7 +1441,7 @@
+ int32_t inum;
+ struct stat st;
+ struct timeval times[2];
+- bool retval = false;
++ bool retval = true; /* default non-fatal */
+
+ /*
+ * Parse the xattr stream. First the part that is the same for all xattrs.
+@@ -1505,7 +1470,6 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "Unable to open file \"%s\": ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1518,7 +1482,6 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg2(100, "Unable to open xattr space on file \"%s\": ERR=%s\n",
+ jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1528,7 +1491,6 @@
+ jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to fchdir to xattr space on file \"%s\" using fd %d: ERR=%s\n",
+ jcr->last_fname, attrdirfd, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1546,7 +1508,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1562,7 +1523,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to open xattr space %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1578,7 +1538,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg4(100, "Unable to fchdir to xattr space %s on file \"%s\" using fd %d: ERR=%s\n",
+ target_attrname, jcr->last_fname, attrdirfd, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1616,8 +1575,7 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to mkfifo xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+- goto cleanup;
++ goto cleanup;
+ }
+ break;
+ case S_IFCHR:
+@@ -1632,7 +1590,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to mknod xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+ break;
+@@ -1649,7 +1606,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to mkdir xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+ }
+@@ -1668,7 +1624,6 @@
+ target_attrname, linked_target, jcr->last_fname, be.bstrerror());
+ Dmsg4(100, "Unable to link xattr %s to %s on file \"%s\": ERR=%s\n",
+ target_attrname, linked_target, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1699,7 +1654,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to open xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+ }
+@@ -1720,7 +1674,6 @@
+ target_attrname, jcr->last_fname);
+ Dmsg2(100, "Unable to restore data of xattr %s on file \"%s\": Not all data available in xattr stream\n",
+ target_attrname, jcr->last_fname);
+-
+ goto cleanup;
+ }
+
+@@ -1732,7 +1685,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to restore data of xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1754,7 +1706,6 @@
+ target_attrname, linked_target, jcr->last_fname, be.bstrerror());
+ Dmsg4(100, "Unable to symlink xattr %s to %s on file \"%s\": ERR=%s\n",
+ target_attrname, linked_target, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+
+@@ -1787,7 +1738,6 @@
+ Dmsg3(100, "Unable to restore owner of xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+ }
+-
+ goto cleanup;
+ }
+ }
+@@ -1813,7 +1763,6 @@
+ target_attrname, jcr->last_fname, be.bstrerror());
+ Dmsg3(100, "Unable to restore filetimes of xattr %s on file \"%s\": ERR=%s\n",
+ target_attrname, jcr->last_fname, be.bstrerror());
+-
+ goto cleanup;
+ }
+ }
+@@ -1831,13 +1780,15 @@
+ jcr->last_fname);
+
+ cleanup:
+- if (attrfd != -1)
++ if (attrfd != -1) {
+ close(attrfd);
+- if (attrdirfd != -1)
++ }
++ if (attrdirfd != -1) {
+ close(attrdirfd);
+- if (filefd != -1)
++ }
++ if (filefd != -1) {
+ close(filefd);
+-
++ }
+ return retval;
+ }
+
+@@ -1859,8 +1810,7 @@
+ jcr->last_fname);
+ Dmsg1(100, "Unable to restore extensible attributes on file \"%s\", filesystem doesn't support this\n",
+ jcr->last_fname);
+-
+- return false;
++ return true;
+ }
+
+ is_extensible = true;
+@@ -1873,13 +1823,11 @@
+ jcr->last_fname);
+ Dmsg1(100, "Unable to restore extended attributes on file \"%s\", filesystem doesn't support this\n",
+ jcr->last_fname);
+-
+- return false;
++ return true;
+ }
+-
+ break;
+ default:
+- return false;
++ return true;
+ }
+
+ /*
+@@ -1889,7 +1837,6 @@
+ getcwd(cwd, sizeof(cwd));
+ retval = solaris_restore_xattrs(jcr, is_extensible);
+ chdir(cwd);
+-
+ return retval;
+ }
+
+@@ -1906,13 +1853,12 @@
+ nr_xattr_saved = 0;
+
+ /*
+- * As we change the cwd in the archive function save the current cwd
+- * for restore after return from the solaris_archive_xattrs function.
++ * As we change the cwd in the save function save the current cwd
++ * for restore after return from the solaris_save_xattrs function.
+ */
+ getcwd(cwd, sizeof(cwd));
+- retval = solaris_archive_xattrs(jcr, NULL, NULL);
++ retval = solaris_save_xattrs(jcr, NULL, NULL);
+ chdir(cwd);
+-
+ drop_xattr_link_cache();
+ }
+
+@@ -1928,7 +1874,10 @@
+ case STREAM_XATTR_SOLARIS:
+ return solaris_extract_xattr(jcr, stream);
+ default:
+- return false;
++ Jmsg2(jcr, M_WARNING, 0,
++ _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
++ jcr->last_fname, stream);
++ return true; /* non-fatal error */
+ }
+ }
+ #endif
--- /dev/null
+From 729f8b83b1002ae272e75a6139631846946f728f Mon Sep 17 00:00:00 2001
+From: Kern Sibbald <kern@sibbald.com>
+Date: Thu, 10 Sep 2009 15:19:13 +0200
+Subject: [PATCH] Add more info when SD connection refused
+
+as mentioned in bug #1371
+---
+ bacula/src/stored/dircmd.c | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c
+index 4f4a2d7..b011802 100644
+--- a/bacula/src/stored/dircmd.c
++++ b/bacula/src/stored/dircmd.c
+@@ -152,7 +152,7 @@ void *handle_connection_request(void *arg)
+ char tbuf[100];
+
+ if (bs->recv() <= 0) {
+- Emsg0(M_ERROR, 0, _("Connection request failed.\n"));
++ Emsg1(M_ERROR, 0, _("Connection request from %s failed.\n"), bs->who());
+ bs->close();
+ return NULL;
+ }
+@@ -162,7 +162,7 @@ void *handle_connection_request(void *arg)
+ */
+ if (bs->msglen < 25 || bs->msglen > (int)sizeof(name)) {
+ Dmsg1(000, "<filed: %s", bs->msg);
+- Emsg1(M_ERROR, 0, _("Invalid connection. Len=%d\n"), bs->msglen);
++ Emsg2(M_ERROR, 0, _("Invalid connection from %s. Len=%d\n"), bs->who(), bs->msglen);
+ bs->close();
+ return NULL;
+ }
+--
+1.6.4.2
+
--- /dev/null
+From 47110b209cb516100d4e3af861b18d5836a585e6 Mon Sep 17 00:00:00 2001
+From: Kern Sibbald <kern@sibbald.com>
+Date: Thu, 10 Sep 2009 15:28:59 +0200
+Subject: [PATCH] Fix seg fault in SD bug #1371
+
+---
+ bacula/src/lib/message.c | 17 +++++++++++------
+ 1 files changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c
+index 7acf744..bc527a7 100644
+--- a/bacula/src/lib/message.c
++++ b/bacula/src/lib/message.c
+@@ -1,7 +1,7 @@
+ /*
+ Bacula® - The Network Backup Solution
+
+- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
++ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+@@ -69,8 +69,8 @@ void create_jcr_key();
+
+ /* Static storage */
+
+-/* Used to allow only one thread close the daemon messages at a time */
+-static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
++/* Allow only one thread to tweak d->fd at a time */
++static pthread_mutex_t fides_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static MSGS *daemon_msgs; /* global messages */
+ static char *catalog_db = NULL; /* database type */
+ static void (*message_callback)(int type, char *msg) = NULL;
+@@ -421,7 +421,6 @@ void close_msg(JCR *jcr)
+
+ if (jcr == NULL) { /* NULL -> global chain */
+ msgs = daemon_msgs;
+- P(mutex); /* only one thread walking the chain */
+ } else {
+ msgs = jcr->jcr_msgs;
+ jcr->jcr_msgs = NULL;
+@@ -429,6 +428,7 @@ void close_msg(JCR *jcr)
+ if (msgs == NULL) {
+ return;
+ }
++ P(fides_mutex);
+ Dmsg1(850, "===Begin close msg resource at %p\n", msgs);
+ cmd = get_pool_memory(PM_MESSAGE);
+ for (d=msgs->dest_chain; d; ) {
+@@ -512,13 +512,12 @@ rem_temp_file:
+ }
+ d = d->next; /* point to next buffer */
+ }
++ V(fides_mutex);
+ free_pool_memory(cmd);
+ Dmsg0(850, "Done walking message chain.\n");
+ if (jcr) {
+ free_msgs_res(msgs);
+ msgs = NULL;
+- } else {
+- V(mutex);
+ }
+ Dmsg0(850, "===End close msg resource\n");
+ }
+@@ -737,6 +736,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
+ case MD_MAIL_ON_ERROR:
+ case MD_MAIL_ON_SUCCESS:
+ Dmsg1(850, "MAIL for following msg: %s", msg);
++ P(fides_mutex);
+ if (!d->fd) {
+ POOLMEM *name = get_pool_memory(PM_MESSAGE);
+ make_unique_mail_filename(jcr, name, d);
+@@ -748,6 +748,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
+ be.bstrerror());
+ d->fd = NULL;
+ free_pool_memory(name);
++ V(fides_mutex);
+ break;
+ }
+ d->mail_filename = name;
+@@ -758,6 +759,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
+ d->max_len = len; /* keep max line length */
+ }
+ fputs(msg, d->fd);
++ V(fides_mutex);
+ break;
+ case MD_APPEND:
+ Dmsg1(850, "APPEND for following msg: %s", msg);
+@@ -767,7 +769,9 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
+ Dmsg1(850, "FILE for following msg: %s", msg);
+ mode = "w+b";
+ send_to_file:
++ P(fides_mutex);
+ if (!d->fd && !open_dest_file(jcr, d, mode)) {
++ V(fides_mutex);
+ break;
+ }
+ fputs(dt, d->fd);
+@@ -781,6 +785,7 @@ send_to_file:
+ fputs(msg, d->fd);
+ }
+ }
++ V(fides_mutex);
+ break;
+ case MD_DIRECTOR:
+ Dmsg1(850, "DIRECTOR for following msg: %s", msg);
+--
+1.6.4.2
+
--- /dev/null
+
+ This patch can be applied to version 3.0.2 and fixes
+ bug #1355 'bacula director crashes with double free
+ in Accurate SQL query'
+
+ Apply it to version 3.0.2 with:
+
+ cd <bacula-source>
+ patch -p2 <3.0.2-accurate.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h
+index 2ff803f..be07e84 100644
+--- a/bacula/src/cats/cats.h
++++ b/bacula/src/cats/cats.h
+@@ -1037,6 +1037,16 @@ struct db_int64_ctx {
+ int count; /* number of values seen */
+ };
+
++/* Call back context for getting a list of comma separated strings from the database */
++class db_list_ctx {
++public:
++ POOLMEM *list; /* list */
++ int count; /* number of values seen */
++
++ db_list_ctx() { list = get_pool_memory(PM_FNAME); *list = 0; count = 0; }
++ ~db_list_ctx() { free_pool_memory(list); list = NULL; }
++};
++
+
+ #include "protos.h"
+ #include "jcr.h"
+diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h
+index ea03a3c..565526a 100644
+--- a/bacula/src/cats/protos.h
++++ b/bacula/src/cats/protos.h
+@@ -1,7 +1,7 @@
+ /*
+ Bacula® - The Network Backup Solution
+
+- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
++ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+@@ -57,6 +57,7 @@ bool db_sql_query(B_DB *mdb, const char *cmd, DB_RESULT_HANDLER *result_handler,
+ void db_start_transaction(JCR *jcr, B_DB *mdb);
+ void db_end_transaction(JCR *jcr, B_DB *mdb);
+ int db_int64_handler(void *ctx, int num_fields, char **row);
++int db_list_handler(void *ctx, int num_fields, char **row);
+ void db_thread_cleanup();
+ void _dbg_print_db(JCR *jcr, FILE *fp);
+
+@@ -106,8 +107,8 @@ int db_get_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cdbr);
+ int db_get_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr);
+ bool db_get_query_dbids(JCR *jcr, B_DB *mdb, POOL_MEM &query, dbid_list &ids);
+ bool db_get_file_list(JCR *jcr, B_DB *mdb, char *jobids, DB_RESULT_HANDLER *result_handler, void *ctx);
+-bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, POOLMEM *jobids);
+-int db_get_int_handler(void *ctx, int num_fields, char **row);
++bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb, JOB_DBR *jr, db_list_ctx *jobids);
++int db_get_int_handler(void *list, int num_fields, char **row);
+
+
+ /* sql_list.c */
+diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c
+index 324d017..e698b5a 100644
+--- a/bacula/src/cats/sql.c
++++ b/bacula/src/cats/sql.c
+@@ -144,7 +144,21 @@ int db_int64_handler(void *ctx, int num_fields, char **row)
+ return 0;
+ }
+
+-
++/*
++ * Use to build a comma separated list of values from a query. "10,20,30"
++ */
++int db_list_handler(void *ctx, int num_fields, char **row)
++{
++ db_list_ctx *lctx = (db_list_ctx *)ctx;
++ if (num_fields == 1 && row[0]) {
++ if (lctx->list[0]) {
++ pm_strcat(lctx->list, ",");
++ }
++ pm_strcat(lctx->list, row[0]);
++ lctx->count++;
++ }
++ return 0;
++}
+
+ /* NOTE!!! The following routines expect that the
+ * calling subroutine sets and clears the mutex
+diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c
+index b9d25bb..62cd07c 100644
+--- a/bacula/src/cats/sql_get.c
++++ b/bacula/src/cats/sql_get.c
+@@ -1,7 +1,7 @@
+ /*
+ Bacula® - The Network Backup Solution
+
+- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
++ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+@@ -1100,7 +1100,7 @@ bool db_get_file_list(JCR *jcr, B_DB *mdb, char *jobids,
+ * TODO: look and merge from ua_restore.c
+ */
+ bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
+- JOB_DBR *jr, POOLMEM *jobids)
++ JOB_DBR *jr, db_list_ctx *jobids)
+ {
+ bool ret=false;
+ char clientid[50], jobid[50], filesetid[50];
+@@ -1111,7 +1111,8 @@ bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
+ time_t StartTime = (jr->StartTime)?jr->StartTime:time(NULL);
+
+ bstrutime(date, sizeof(date), StartTime + 1);
+- jobids[0]='\0';
++ jobids->list[0] = 0;
++ jobids->count = 0;
+
+ /* First, find the last good Full backup for this job/client/fileset */
+ Mmsg(query,
+@@ -1177,8 +1178,8 @@ bool db_accurate_get_jobids(JCR *jcr, B_DB *mdb,
+
+ /* build a jobid list ie: 1,2,3,4 */
+ Mmsg(query, "SELECT JobId FROM btemp3%s ORDER by JobTDate", jobid);
+- db_sql_query(mdb, query.c_str(), db_get_int_handler, jobids);
+- Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids);
++ db_sql_query(mdb, query.c_str(), db_list_handler, jobids);
++ Dmsg1(1, "db_accurate_get_jobids=%s\n", jobids->list);
+ ret = true;
+
+ bail_out:
+@@ -1188,19 +1189,4 @@ bail_out:
+ return ret;
+ }
+
+-/*
+- * Use to build a string of int list from a query. "10,20,30"
+- */
+-int db_get_int_handler(void *ctx, int num_fields, char **row)
+-{
+- POOLMEM *ret = (POOLMEM *)ctx;
+- if (num_fields == 1) {
+- if (ret[0]) {
+- pm_strcat(ret, ",");
+- }
+- pm_strcat(ret, row[0]);
+- }
+- return 0;
+-}
+-
+ #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL || HAVE_DBI */
+diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c
+index 029dfa0..1837a6b 100644
+--- a/bacula/src/dird/backup.c
++++ b/bacula/src/dird/backup.c
+@@ -131,42 +131,37 @@ static int accurate_list_handler(void *ctx, int num_fields, char **row)
+ bool send_accurate_current_files(JCR *jcr)
+ {
+ POOL_MEM buf;
++ db_list_ctx jobids;
++ db_list_ctx nb;
+
+ if (!jcr->accurate || job_canceled(jcr) || jcr->get_JobLevel()==L_FULL) {
+ return true;
+ }
+- POOLMEM *jobids = get_pool_memory(PM_FNAME);
+
+- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
+-
+- if (*jobids == 0) {
+- free_pool_memory(jobids);
++ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
++ if (jobids.count == 0) {
+ Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
+ return false;
+ }
++
+ if (jcr->JobId) { /* display the message only for real jobs */
+ Jmsg(jcr, M_INFO, 0, _("Sending Accurate information.\n"));
+ }
+ /* to be able to allocate the right size for htable */
+- POOLMEM *nb = get_pool_memory(PM_FNAME);
+- *nb = 0; /* clear buffer */
+- Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)",jobids);
+- db_sql_query(jcr->db, buf.c_str(), db_get_int_handler, nb);
+- Dmsg2(200, "jobids=%s nb=%s\n", jobids, nb);
+- jcr->file_bsock->fsend("accurate files=%s\n", nb);
++ Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)",jobids.list);
++ db_sql_query(jcr->db, buf.c_str(), db_list_handler, &nb);
++ Dmsg2(200, "jobids=%s nb=%s\n", jobids.list, nb.list);
++ jcr->file_bsock->fsend("accurate files=%s\n", nb.list);
+
+ if (!db_open_batch_connexion(jcr, jcr->db)) {
+ Jmsg0(jcr, M_FATAL, 0, "Can't get dedicate sql connexion");
+ return false;
+ }
+
+- db_get_file_list(jcr, jcr->db_batch, jobids, accurate_list_handler, (void *)jcr);
++ db_get_file_list(jcr, jcr->db_batch, jobids.list, accurate_list_handler, (void *)jcr);
+
+ /* TODO: close the batch connexion ? (can be used very soon) */
+
+- free_pool_memory(jobids);
+- free_pool_memory(nb);
+-
+ jcr->file_bsock->signal(BNET_EOD);
+
+ return true;
+diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c
+index 3d5fc1d..028be52 100644
+--- a/bacula/src/dird/ua_output.c
++++ b/bacula/src/dird/ua_output.c
+@@ -456,7 +456,7 @@ static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist)
+ }
+ list_nextvol(ua, n);
+ } else if (strcasecmp(ua->argk[i], NT_("copies")) == 0) {
+- char *jobids=NULL;
++ char *jobids = NULL;
+ uint32_t limit=0;
+ for (j=i+1; j<ua->argc; j++) {
+ if (strcasecmp(ua->argk[j], NT_("jobid")) == 0 && ua->argv[j]) {
+diff --git a/bacula/src/dird/ua_restore.c b/bacula/src/dird/ua_restore.c
+index 366d9ed..16f5215 100644
+--- a/bacula/src/dird/ua_restore.c
++++ b/bacula/src/dird/ua_restore.c
+@@ -1,7 +1,7 @@
+ /*
+ Bacula® - The Network Backup Solution
+
+- Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
++ Copyright (C) 2002-2009 Free Software Foundation Europe e.V.
+
+ The main author of Bacula is Kern Sibbald, with contributions from
+ many others, a complete list can be found in the file AUTHORS.
+@@ -556,6 +556,7 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
+ char *fname;
+ int len;
+ bool gui_save;
++ db_list_ctx jobids;
+
+ start_prompt(ua, _("To select the JobIds, you have the following choices:\n"));
+ for (int i=0; list[i]; i++) {
+@@ -752,9 +753,10 @@ static int user_select_jobids_or_files(UAContext *ua, RESTORE_CTX *rx)
+ return 0;
+ }
+ jr.JobLevel = L_INCREMENTAL; /* Take Full+Diff+Incr */
+- if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, rx->JobIds)) {
++ if (!db_accurate_get_jobids(ua->jcr, ua->db, &jr, &jobids)) {
+ return 0;
+ }
++ pm_strcpy(rx->JobIds, jobids.list);
+ Dmsg1(30, "Item 12: jobids = %s\n", rx->JobIds);
+ break;
+ case 12: /* Cancel or quit */
+diff --git a/bacula/src/dird/vbackup.c b/bacula/src/dird/vbackup.c
+index 45a1f7e..e75d08d 100644
+--- a/bacula/src/dird/vbackup.c
++++ b/bacula/src/dird/vbackup.c
+@@ -50,7 +50,7 @@
+
+ static const int dbglevel = 10;
+
+-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids);
++static bool create_bootstrap_file(JCR *jcr, char *jobids);
+ void vbackup_cleanup(JCR *jcr, int TermCode);
+
+ /*
+@@ -135,6 +135,7 @@ bool do_vbackup(JCR *jcr)
+ char ed1[100];
+ BSOCK *sd;
+ char *p;
++ db_list_ctx jobids;
+
+ Dmsg2(100, "rstorage=%p wstorage=%p\n", jcr->rstorage, jcr->wstorage);
+ Dmsg2(100, "Read store=%s, write store=%s\n",
+@@ -157,28 +158,27 @@ bool do_vbackup(JCR *jcr)
+ _("This Job is not an Accurate backup so is not equivalent to a Full backup.\n"));
+ }
+
+- POOLMEM *jobids = get_pool_memory(PM_FNAME);
+ jcr->jr.JobLevel = L_VIRTUAL_FULL;
+- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
+- jcr->jr.JobLevel = L_FULL;
+- Dmsg1(10, "Accurate jobids=%s\n", jobids);
+- if (*jobids == 0) {
+- free_pool_memory(jobids);
++ db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
++ Dmsg1(10, "Accurate jobids=%s\n", jobids.list);
++ if (jobids.count == 0) {
+ Jmsg(jcr, M_FATAL, 0, _("No previous Jobs found.\n"));
+ return false;
+ }
+
++ jcr->jr.JobLevel = L_FULL;
++
+ /*
+ * Now we find the last job that ran and store it's info in
+ * the previous_jr record. We will set our times to the
+ * values from that job so that anything changed after that
+ * time will be picked up on the next backup.
+ */
+- p = strrchr(jobids, ','); /* find last jobid */
++ p = strrchr(jobids.list, ','); /* find last jobid */
+ if (p != NULL) {
+ p++;
+ } else {
+- p = jobids;
++ p = jobids.list;
+ }
+ memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
+ jcr->previous_jr.JobId = str_to_int64(p);
+@@ -189,12 +189,10 @@ _("This Job is not an Accurate backup so is not equivalent to a Full backup.\n")
+ return false;
+ }
+
+- if (!create_bootstrap_file(jcr, jobids)) {
++ if (!create_bootstrap_file(jcr, jobids.list)) {
+ Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
+- free_pool_memory(jobids);
+ return false;
+ }
+- free_pool_memory(jobids);
+
+ /*
+ * Open a message channel connection with the Storage
+@@ -476,7 +474,7 @@ int insert_bootstrap_handler(void *ctx, int num_fields, char **row)
+ }
+
+
+-static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids)
++static bool create_bootstrap_file(JCR *jcr, char *jobids)
+ {
+ RESTORE_CTX rx;
+ UAContext *ua;
--- /dev/null
+>From f182fe49fca2b2e3009f26fbf6197f8c046835ad Mon Sep 17 00:00:00 2001
+From: Marco van Wieringen <mvw@planets.elm.net>
+Date: Sun, 6 Sep 2009 17:56:20 +0200
+Subject: [PATCH] This patch should fix bug #1365
+
+---
+ bacula/src/filed/restore.c | 15 +++++++--------
+ 1 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c
+index a4ee03a..4400e14 100644
+--- a/bacula/src/filed/restore.c
++++ b/bacula/src/filed/restore.c
+@@ -120,7 +120,7 @@ static void close_previous_stream(r_ctx &rctx);
+
+
+ static bool verify_signature(JCR *jcr, r_ctx &rctx);
+-int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
++int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
+ uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx);
+ bool flush_cipher(JCR *jcr, BFILE *bfd, uint64_t *addr, int flags,
+ RESTORE_CIPHER_CTX *cipher_ctx);
+@@ -508,8 +508,9 @@ void do_restore(JCR *jcr)
+ rctx.flags |= FO_WIN32DECOMP; /* "decompose" BackupWrite data */
+ }
+
+- if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fileAddr,
++ if (extract_data(jcr, &rctx.bfd, sd->msg, sd->msglen, &rctx.fileAddr,
+ rctx.flags, &rctx.cipher_ctx) < 0) {
++ rctx.extract = false;
+ bclose(&rctx.bfd);
+ continue;
+ }
+@@ -558,8 +559,9 @@ void do_restore(JCR *jcr)
+ Dmsg0(130, "Restoring resource fork\n");
+ }
+
+- if (extract_data(jcr, rctx, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
++ if (extract_data(jcr, &rctx.forkbfd, sd->msg, sd->msglen, &rctx.fork_addr, rctx.fork_flags,
+ &rctx.fork_cipher_ctx) < 0) {
++ rctx.extract = false;
+ bclose(&rctx.forkbfd);
+ continue;
+ }
+@@ -1069,10 +1071,9 @@ bool store_data(JCR *jcr, BFILE *bfd, char *data, const int32_t length, bool win
+ * The flags specify whether to use sparse files or compression.
+ * Return value is the number of bytes written, or -1 on errors.
+ */
+-int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
+- uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
++int32_t extract_data(JCR *jcr, BFILE *bfd, POOLMEM *buf, int32_t buflen,
++ uint64_t *addr, int flags, RESTORE_CIPHER_CTX *cipher_ctx)
+ {
+- BFILE *bfd = &rctx.bfd;
+ char *wbuf; /* write buffer */
+ uint32_t wsize; /* write size */
+ uint32_t rsize; /* read size */
+@@ -1172,9 +1173,7 @@ int32_t extract_data(JCR *jcr, r_ctx &rctx, POOLMEM *buf, int32_t buflen,
+ return wsize;
+
+ bail_out:
+- rctx.extract = false;
+ return -1;
+-
+ }
+
+
+--
+1.5.6.5
+
--- /dev/null
+>From 297ec720cf512a6b5045c962bfb8a2f134ac77b0 Mon Sep 17 00:00:00 2001
+From: Marco van Wieringen <mvw@planets.elm.net>
+Date: Sun, 6 Sep 2009 18:06:48 +0200
+Subject: [PATCH] This patch should fix bug #1366
+
+---
+ bacula/src/filed/restore.c | 11 ++++++++++-
+ 1 files changed, 10 insertions(+), 1 deletions(-)
+
+diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c
+index 4400e14..cbb0889 100644
+--- a/bacula/src/filed/restore.c
++++ b/bacula/src/filed/restore.c
+@@ -367,7 +367,6 @@ void do_restore(JCR *jcr)
+ rctx.extract = true;
+ /* FALLTHROUGH */
+ case CF_CREATED: /* File created, but there is no content */
+- jcr->JobFiles++;
+ rctx.fileAddr = 0;
+ print_ls_output(jcr, attr);
+
+@@ -377,7 +376,17 @@ void do_restore(JCR *jcr)
+ if (attr->type == FT_REG && rsrc_len > 0) {
+ rctx.extract = true;
+ }
++
++ /*
++ * Count the resource forks not as regular files being restored.
++ */
++ if (rsrc_len == 0) {
++ jcr->JobFiles++;
++ }
++ } else {
++ jcr->JobFiles++;
+ }
++
+ if (!rctx.extract) {
+ /* set attributes now because file will not be extracted */
+ if (jcr->plugin) {
+--
+1.5.6.5
+
--- /dev/null
+From 4d2f1c844510c9abb9ecf6f0283437862c4a3bfb Mon Sep 17 00:00:00 2001
+From: Eric Bollengier <eric@eb.homelinux.org>
+Date: Wed, 9 Sep 2009 14:18:57 +0200
+Subject: [PATCH] Fix #1370 about the implementation of the "Exclude Dir Containing" option on FD.
+
+---
+ bacula/src/filed/job.c | 20 +++++++++++---------
+ bacula/src/findlib/find.c | 3 ++-
+ bacula/src/findlib/find.h | 2 +-
+ 3 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c
+index 4054b29..549d6b7 100644
+--- a/bacula/src/filed/job.c
++++ b/bacula/src/filed/job.c
+@@ -342,13 +342,13 @@ void *handle_client_request(void *dirp)
+ fo->base.destroy();
+ fo->fstype.destroy();
+ fo->drivetype.destroy();
+- if (fo->ignoredir != NULL) {
+- free(fo->ignoredir);
+- }
+ }
+ incexe->opts_list.destroy();
+ incexe->name_list.destroy();
+ incexe->plugin_list.destroy();
++ if (incexe->ignoredir) {
++ free(incexe->ignoredir);
++ }
+ }
+ fileset->include_list.destroy();
+
+@@ -371,6 +371,9 @@ void *handle_client_request(void *dirp)
+ incexe->opts_list.destroy();
+ incexe->name_list.destroy();
+ incexe->plugin_list.destroy();
++ if (incexe->ignoredir) {
++ free(incexe->ignoredir);
++ }
+ }
+ fileset->exclude_list.destroy();
+ free(fileset);
+@@ -876,9 +879,8 @@ static void add_fileset(JCR *jcr, const char *item)
+ state = state_options;
+ break;
+ case 'Z':
+- current_opts = start_options(ff);
+- current_opts->ignoredir = bstrdup(item);
+- state = state_options;
++ state = state_include;
++ fileset->incexe->ignoredir = bstrdup(item);
+ break;
+ case 'D':
+ current_opts = start_options(ff);
+@@ -941,9 +943,9 @@ static bool term_fileset(JCR *jcr)
+ for (k=0; k<fo->drivetype.size(); k++) {
+ Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
+ }
+- if (fo->ignoredir) {
+- Dmsg1(400, "Z %s\n", fo->ignoredir);
+- }
++ }
++ if (incexe->ignoredir) {
++ Dmsg1(400, "Z %s\n", incexe->ignoredir);
+ }
+ dlistString *node;
+ foreach_dlist(node, &incexe->name_list) {
+diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c
+index 81e887a..d089b70 100644
+--- a/bacula/src/findlib/find.c
++++ b/bacula/src/findlib/find.c
+@@ -274,11 +274,12 @@ static bool accept_file(FF_PKT *ff)
+ basename = ff->fname;
+ }
+
++ ff->ignoredir = incexe->ignoredir;
++
+ 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->ignoredir = fo->ignoredir;
+ ff->fstypes = fo->fstype;
+ ff->drivetypes = fo->drivetype;
+
+diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h
+index 030aa3f..ff9be47 100644
+--- a/bacula/src/findlib/find.h
++++ b/bacula/src/findlib/find.h
+@@ -151,7 +151,6 @@ struct findFOPTS {
+ alist base; /* list of base names */
+ alist fstype; /* file system type limitation */
+ alist drivetype; /* drive type limitation */
+- char *ignoredir; /* ignore directories with this file */
+ };
+
+
+@@ -161,6 +160,7 @@ struct findINCEXE {
+ alist opts_list; /* options list */
+ dlist name_list; /* filename list -- holds dlistString */
+ dlist plugin_list; /* plugin list -- holds dlistString */
++ char *ignoredir; /* ignore directories with this file */
+ };
+
+ /*
+--
+1.6.3.1
+
--- /dev/null
+From aaf17ad370610f17fc998ff9aeb9e6d9e8832787 Mon Sep 17 00:00:00 2001
+From: Eric Bollengier <eric@eb.homelinux.org>
+Date: Wed, 9 Sep 2009 16:46:36 +0200
+Subject: [PATCH 4/4] Fix Exclude Dir Containing ignored when scanning the top_level dir
+
+---
+ bacula/src/findlib/find.c | 2 --
+ bacula/src/findlib/find.h | 1 -
+ bacula/src/findlib/find_one.c | 41 +++++++++++++++++++++++++----------------
+ 3 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c
+index d089b70..38344f3 100644
+--- a/bacula/src/findlib/find.c
++++ b/bacula/src/findlib/find.c
+@@ -274,8 +274,6 @@ static bool accept_file(FF_PKT *ff)
+ basename = ff->fname;
+ }
+
+- ff->ignoredir = incexe->ignoredir;
+-
+ for (j = 0; j < incexe->opts_list.size(); j++) {
+ findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+ ff->flags = fo->flags;
+diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h
+index ff9be47..707f529 100644
+--- a/bacula/src/findlib/find.h
++++ b/bacula/src/findlib/find.h
+@@ -215,7 +215,6 @@ struct FF_PKT {
+ uint32_t flags; /* backup options */
+ int GZIP_level; /* compression level */
+ int strip_path; /* strip path count */
+- char *ignoredir; /* ignore directories with this file */
+ bool cmd_plugin; /* set if we have a command plugin */
+ alist fstypes; /* allowed file system types */
+ alist drivetypes; /* allowed drive types */
+diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c
+index 5619ea4..f4f2e7b 100644
+--- a/bacula/src/findlib/find_one.c
++++ b/bacula/src/findlib/find_one.c
+@@ -299,6 +299,29 @@ static bool check_changes(JCR *jcr, FF_PKT *ff_pkt)
+ return true;
+ }
+
++static bool have_ignoredir(FF_PKT *ff_pkt)
++{
++ struct stat sb;
++ char tmp_name[MAXPATHLEN];
++ char *ignoredir = ff_pkt->fileset->incexe->ignoredir;
++
++ if (ignoredir) {
++ if (strlen(ff_pkt->fname) + strlen(ignoredir) + 2 > MAXPATHLEN) {
++ return false;
++ }
++
++ strcpy(tmp_name, ff_pkt->fname);
++ strcat(tmp_name, "/");
++ strcat(tmp_name, ignoredir);
++ if (stat(tmp_name, &sb) == 0) {
++ Dmsg2(100, "Directory '%s' ignored (found %s)\n",
++ ff_pkt->fname, ignoredir);
++ return true; /* Just ignore this directory */
++ }
++ }
++ return false;
++}
++
+ /*
+ * Find a single file.
+ * handle_file is the callback for handling the file.
+@@ -551,22 +574,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt,
+ * Ignore this directory and everything below if the file .nobackup
+ * (or what is defined for IgnoreDir in this fileset) exists
+ */
+- if (ff_pkt->ignoredir != NULL) {
+- struct stat sb;
+- char fname[MAXPATHLEN];
+-
+- if (strlen(ff_pkt->fname) + strlen("/") +
+- strlen(ff_pkt->ignoredir) + 1 > MAXPATHLEN)
+- return 1; /* Is this wisdom? */
+-
+- strcpy(fname, ff_pkt->fname);
+- strcat(fname, "/");
+- strcat(fname, ff_pkt->ignoredir);
+- if (stat(fname, &sb) == 0) {
+- Dmsg2(100, "Directory '%s' ignored (found %s)\n",
+- ff_pkt->fname, ff_pkt->ignoredir);
+- return 1; /* Just ignore this directory */
+- }
++ if (have_ignoredir(ff_pkt)) {
++ return 1; /* Just ignore this directory */
+ }
+
+ /* Build a canonical directory name with a trailing slash in link var */
+--
+1.6.3.1
+
--- /dev/null
+From af393297b65456d07122f3e372ee3985dc747f06 Mon Sep 17 00:00:00 2001
+From: Eric Bollengier <eric@eb.homelinux.org>
+Date: Wed, 9 Sep 2009 10:24:20 +0200
+Subject: [PATCH] Fix #1369 about segfault when using ExcludeDirContaining before defining Options{} block.
+
+---
+ bacula/src/dird/dird_conf.c | 6 ++++++
+ bacula/src/dird/dird_conf.h | 2 +-
+ bacula/src/dird/fd_cmds.c | 6 +++---
+ bacula/src/dird/inc_conf.c | 2 +-
+ 4 files changed, 11 insertions(+), 5 deletions(-)
+
+diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c
+index d9995ad..0819e76 100644
+--- a/bacula/src/dird/dird_conf.c
++++ b/bacula/src/dird/dird_conf.c
+@@ -806,6 +806,9 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
+ }
+ sendit(sock, " N\n");
+ }
++ if (incexe->ignoredir) {
++ sendit(sock, " Z %s\n", incexe->ignoredir);
++ }
+ for (j=0; j<incexe->name_list.size(); j++) {
+ sendit(sock, " I %s\n", incexe->name_list.get(j));
+ }
+@@ -1026,6 +1029,9 @@ static void free_incexe(INCEXE *incexe)
+ if (incexe->opts_list) {
+ free(incexe->opts_list);
+ }
++ if (incexe->ignoredir) {
++ free(incexe->ignoredir);
++ }
+ free(incexe);
+ }
+
+diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h
+index 231dfab..55706ec 100644
+--- a/bacula/src/dird/dird_conf.h
++++ b/bacula/src/dird/dird_conf.h
+@@ -462,7 +462,6 @@ struct FOPTS {
+ alist drivetype; /* drive type limitation */
+ char *reader; /* reader program */
+ char *writer; /* writer program */
+- char *ignoredir; /* ignoredir string */
+ char *plugin; /* plugin program */
+ };
+
+@@ -474,6 +473,7 @@ struct INCEXE {
+ int32_t num_opts; /* number of options items */
+ alist name_list; /* filename list -- holds char * */
+ alist plugin_list; /* filename list for plugins */
++ char *ignoredir; /* ignoredir string */
+ };
+
+ /*
+diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c
+index 71d9fc3..2ef63d9 100644
+--- a/bacula/src/dird/fd_cmds.c
++++ b/bacula/src/dird/fd_cmds.c
+@@ -354,6 +354,9 @@ static bool send_fileset(JCR *jcr)
+ ie = fileset->exclude_items[i];
+ fd->fsend("E\n");
+ }
++ if (ie->ignoredir) {
++ bnet_fsend(fd, "Z %s\n", ie->ignoredir);
++ }
+ for (j=0; j<ie->num_opts; j++) {
+ FOPTS *fo = ie->opts_list[j];
+ fd->fsend("O %s\n", fo->opts);
+@@ -399,9 +402,6 @@ static bool send_fileset(JCR *jcr)
+ if (fo->plugin) {
+ fd->fsend("G %s\n", fo->plugin);
+ }
+- if (fo->ignoredir) {
+- bnet_fsend(fd, "Z %s\n", fo->ignoredir);
+- }
+ if (fo->reader) {
+ fd->fsend("D %s\n", fo->reader);
+ }
+diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c
+index ef15d3f..aedde44 100644
+--- a/bacula/src/dird/inc_conf.c
++++ b/bacula/src/dird/inc_conf.c
+@@ -588,7 +588,7 @@ static void store_excludedir(LEX *lc, RES_ITEM2 *item, int index, int pass, bool
+ }
+ token = lex_get_token(lc, T_NAME);
+ if (pass == 1) {
+- res_incexe.current_opts->ignoredir = bstrdup(lc->str);
++ res_incexe.ignoredir = bstrdup(lc->str);
+ }
+ scan_to_eol(lc);
+ }
+--
+1.6.3.1
+
--- /dev/null
+ This patch can be applied to version 3.0.2 and fixes
+ bug #1368 ASSERT Failure on MacOS. Unfortunately,
+ MacOS programmers do not respect/implement POSIX
+ pathconf().
+
+ Apply it to version 3.0.2 with:
+
+ cd <bacula-source>
+ patch -p2 <3.0.2-mac-path-len.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+
+diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c
+index ac9e4ce..81e887a 100644
+--- a/bacula/src/findlib/find.c
++++ b/bacula/src/findlib/find.c
+@@ -67,13 +67,13 @@ FF_PKT *init_find_files()
+
+ /* Get system path and filename maximum lengths */
+ path_max = pathconf(".", _PC_PATH_MAX);
+- if (path_max < 1024) {
+- path_max = 1024;
++ if (path_max < 2048) {
++ path_max = 2048;
+ }
+
+ name_max = pathconf(".", _PC_NAME_MAX);
+- if (name_max < 1024) {
+- name_max = 1024;
++ if (name_max < 2048) {
++ name_max = 2048;
+ }
+ path_max++; /* add for EOS */
+ name_max++; /* add for EOS */
--- /dev/null
+commit 6a6cba0ab43be4ba5572b408c3c4fb79352a5273
+Author: Eric Bollengier <eric@eb.homelinux.org>
+Date: Thu Sep 3 08:15:54 2009 +0200
+
+ Fix #1364 and #1363 about compression buffer error.
+
+diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c
+index 808daec..a4ee03a 100644
+--- a/bacula/src/filed/restore.c
++++ b/bacula/src/filed/restore.c
+@@ -207,7 +207,7 @@ void do_restore(JCR *jcr)
+
+ if (have_libz) {
+ uint32_t compress_buf_size = jcr->buf_size + 12 + ((jcr->buf_size+999) / 1000) + 100;
+- jcr->compress_buf = (char *)bmalloc(compress_buf_size);
++ jcr->compress_buf = get_memory(compress_buf_size);
+ jcr->compress_buf_size = compress_buf_size;
+ }
+
+@@ -802,7 +802,7 @@ ok_out:
+ }
+
+ if (jcr->compress_buf) {
+- free(jcr->compress_buf);
++ free_pool_memory(jcr->compress_buf);
+ jcr->compress_buf = NULL;
+ jcr->compress_buf_size = 0;
+ }
+@@ -1007,10 +1007,18 @@ bool decompress_data(JCR *jcr, char **data, uint32_t *length)
+ */
+ compress_len = jcr->compress_buf_size;
+ Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
+- if ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
+- (const Byte *)*data, (uLong)*length)) != Z_OK) {
++ while ((stat=uncompress((Byte *)jcr->compress_buf, &compress_len,
++ (const Byte *)*data, (uLong)*length)) == Z_BUF_ERROR)
++ {
++ /* The buffer size is too small, try with a bigger one */
++ compress_len = jcr->compress_buf_size = jcr->compress_buf_size + jcr->compress_buf_size >> 1;
++ Dmsg2(200, "Comp_len=%d msglen=%d\n", compress_len, *length);
++ jcr->compress_buf = check_pool_memory_size(jcr->compress_buf,
++ compress_len);
++ }
++ if (stat != Z_OK) {
+ Qmsg(jcr, M_ERROR, 0, _("Uncompression error on file %s. ERR=%s\n"),
+- jcr->last_fname, zlib_strerror(stat));
++ jcr->last_fname, zlib_strerror(stat));
+ return false;
+ }
+ *data = jcr->compress_buf;
+diff --git a/bacula/src/stored/bextract.c b/bacula/src/stored/bextract.c
+index 1a8c67f..5786a4c 100644
+--- a/bacula/src/stored/bextract.c
++++ b/bacula/src/stored/bextract.c
+@@ -438,9 +438,16 @@ static bool record_cb(DCR *dcr, DEV_RECORD *rec)
+ wbuf = rec->data;
+ wsize = rec->data_len;
+ }
+- compress_len = compress_buf_size;
+- if ((stat=uncompress((Bytef *)compress_buf, &compress_len,
+- (const Bytef *)wbuf, (uLong)wsize) != Z_OK)) {
++
++ while ((stat=uncompress((Byte *)compress_buf, &compress_len,
++ (const Byte *)wbuf, (uLong)wsize)) == Z_BUF_ERROR)
++ {
++ /* The buffer size is too small, try with a bigger one */
++ compress_len = compress_len + compress_len >> 1;
++ compress_buf = check_pool_memory_size(compress_buf,
++ compress_len);
++ }
++ if (stat != Z_OK) {
+ Emsg1(M_ERROR, 0, _("Uncompression error. ERR=%d\n"), stat);
+ extract = false;
+ return true;