+++ /dev/null
-
-This patch fixes a bug where the enable_acl=yes flag was not
-being properly received by the File daemon.
-It can be applied to version 1.34.6 with the following:
-
- cd <bacula-source>
- patch -p0 <1.34.6-ACL.patch
- make
- make install
- ...
-
-Index: src/filed/job.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/filed/job.c,v
-retrieving revision 1.78
-diff -u -r1.78 job.c
---- src/filed/job.c 12 Jun 2004 12:38:16 -0000 1.78
-+++ src/filed/job.c 15 Oct 2004 07:20:28 -0000
-@@ -833,6 +833,9 @@
- case 'k':
- fo->flags |= FO_KEEPATIME;
- break;
-+ case 'A':
-+ fo->flags |= FO_ACL;
-+ break;
- case 'V': /* verify options */
- /* Copy Verify Options */
- for (j=0; *p && *p != ':'; p++) {
+++ /dev/null
-
-In some cases, Bacula will get an error
-on a tape and not be able to write and EOF mark. In this
-case, the tape will no longer be readable. When this happens,
-Bacula tries to plunge on but gets into lots of trouble.
-This patch should fix that by immediately marking the Job
-in error, and by avoiding running through code that doesn't
-make any sense after a fatal error.
-
-Apply the patch to Bacula 1.34.6 (possibly earlier versions)
-with:
-
- cd <bacula-source>
- patch -p0 <1.34.6-block.patch
- make
- make install
- ...
-
-Index: src/stored/block.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/block.c,v
-retrieving revision 1.74.2.1
-diff -u -r1.74.2.1 block.c
---- src/stored/block.c 20 Jun 2004 11:43:04 -0000 1.74.2.1
-+++ src/stored/block.c 23 Aug 2004 19:02:10 -0000
-@@ -356,7 +356,7 @@
- /* Create a jobmedia record for this job */
- if (!dir_create_jobmedia_record(jcr)) {
- dev->dev_errno = EIO;
-- Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
-+ Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
- jcr->VolCatInfo.VolCatName, jcr->Job);
- set_new_volume_parameters(jcr, dev);
- stat = 0;
-@@ -372,7 +372,11 @@
- }
-
- if (!write_block_to_dev(dcr, block)) {
-- stat = fixup_device_block_write_error(jcr, dev, block);
-+ if (job_canceled(jcr)) {
-+ stat = 0;
-+ } else {
-+ stat = fixup_device_block_write_error(jcr, dev, block);
-+ }
- }
-
- bail_out:
-@@ -393,7 +397,7 @@
- ssize_t stat = 0;
- uint32_t wlen; /* length to write */
- int hit_max1, hit_max2;
-- bool ok;
-+ bool ok = true;
- DEVICE *dev = dcr->dev;
- JCR *jcr = dcr->jcr;
-
-@@ -463,9 +467,9 @@
- edit_uint64_with_commas(max_cap, ed1), dev->dev_name);
- block->write_failed = true;
- if (weof_dev(dev, 1) != 0) { /* end tape */
-- Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
-+ Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
- dev->VolCatInfo.VolCatErrors++;
-- }
-+ }
- /* Don't do update after second EOF or file count will be wrong */
- Dmsg0(100, "dir_update_volume_info\n");
- dev->VolCatInfo.VolCatFiles = dev->file;
-@@ -485,7 +489,7 @@
-
- if (dev_state(dev, ST_TAPE) && weof_dev(dev, 1) != 0) { /* write eof */
- /* Write EOF */
-- Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
-+ Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
- block->write_failed = true;
- dev->VolCatInfo.VolCatErrors++;
- dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
-@@ -559,18 +563,18 @@
- block->write_failed = true;
- if (weof_dev(dev, 1) != 0) { /* end the tape */
- dev->VolCatInfo.VolCatErrors++;
-- Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
-+ Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg);
-+ ok = false;
- }
- Dmsg0(100, "dir_update_volume_info\n");
- dev->VolCatInfo.VolCatFiles = dev->file;
- dir_update_volume_info(jcr, dev, 0);
-- if (dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) { /* end the tape */
-+ if (ok && dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) { /* end the tape */
- dev->VolCatInfo.VolCatErrors++;
- Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
- }
- dev->state |= (ST_EOF | ST_EOT | ST_WEOT);
-
-- ok = true;
- #define CHECK_LAST_BLOCK
- #ifdef CHECK_LAST_BLOCK
- /*
-@@ -580,7 +584,7 @@
- * then re-read it and verify that the block number is
- * correct.
- */
-- if (dev->state & ST_TAPE && dev_cap(dev, CAP_BSR)) {
-+ if (ok && dev->state & ST_TAPE && dev_cap(dev, CAP_BSR)) {
-
- /* Now back up over what we wrote and read the last block */
- if (!bsf_dev(dev, 1)) {
+++ /dev/null
-
- This patch fixes two problems: 1. A deadlock between the job
- queue scheduler and the watchdog thread. 2. A bad initialization
- of the watchdog queue which could cause memory corruption. It also
- reduces the watchdog granularity from 1 second to 10 seconds.
-
- Apply the patch to Bacula 1.34.6 (probably any 1.34.x version) with:
-
- cd <bacula-source>
- patch -p0 <1.34.6-deadlock.patch
- make
- ...
-
-
-Index: src/dird/jobq.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/jobq.c,v
-retrieving revision 1.19
-diff -u -r1.19 jobq.c
---- src/dird/jobq.c 1 Jun 2004 20:10:04 -0000 1.19
-+++ src/dird/jobq.c 9 Aug 2004 06:08:08 -0000
-@@ -501,8 +501,10 @@
- jcr->db = NULL;
- }
- Dmsg1(300, "====== Termination job=%d\n", jcr->JobId);
-+ V(jq->mutex); /* release internal job queue lock */
- free_jcr(jcr);
- free(je); /* release job entry */
-+ P(jq->mutex); /* acquire internal job queue lock */
- }
- /*
- * If any job in the wait queue can be run,
-Index: src/lib/watchdog.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/lib/watchdog.c,v
-retrieving revision 1.27
-diff -u -r1.27 watchdog.c
---- src/lib/watchdog.c 1 Apr 2004 16:37:01 -0000 1.27
-+++ src/lib/watchdog.c 9 Aug 2004 06:08:08 -0000
-@@ -32,11 +32,12 @@
-
- /* Exported globals */
- time_t watchdog_time = 0; /* this has granularity of SLEEP_TIME */
-+time_t watchdog_sleep_time = 10; /* examine things every 10 seconds */
-
--#define SLEEP_TIME 1 /* examine things every second */
-
- /* Forward referenced functions */
--static void *watchdog_thread(void *arg);
-+void *watchdog_thread(void *arg);
-+
- static void wd_lock();
- static void wd_unlock();
-
-@@ -71,8 +72,8 @@
- Emsg1(M_ABORT, 0, _("Unable to initialize watchdog lock. ERR=%s\n"),
- strerror(errstat));
- }
-- wd_queue = new dlist(wd_queue, &dummy->link);
-- wd_inactive = new dlist(wd_inactive, &dummy->link);
-+ wd_queue = new dlist(dummy, &dummy->link);
-+ wd_inactive = new dlist(dummy, &dummy->link);
-
- if ((stat = pthread_create(&wd_tid, NULL, watchdog_thread, NULL)) != 0) {
- return stat;
-@@ -214,7 +215,7 @@
- return ret;
- }
-
--static void *watchdog_thread(void *arg)
-+void *watchdog_thread(void *arg)
- {
- Dmsg0(400, "NicB-reworked watchdog thread entered\n");
-
-@@ -259,7 +260,7 @@
- }
- wd_unlock();
- unlock_jcr_chain();
-- bmicrosleep(SLEEP_TIME, 0);
-+ bmicrosleep(watchdog_sleep_time, 0);
- }
-
- Dmsg0(400, "NicB-reworked watchdog thread exited\n");
+++ /dev/null
-
- Patch to allow more natural input of time durations.
- Permitted form is "1 day 2 hours 5 sec" with and without
- spaces. The different duration specifications (day, hour, ...)
- can be in any order.
- Apply to version 1.34.6 with:
-
- cd <bacula-source>
- patch -p0 <1.34.6-duration.patch
- make
- ...
-
-Index: src/dird/ua_cmds.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_cmds.c,v
-retrieving revision 1.112
-diff -u -r1.112 ua_cmds.c
---- src/dird/ua_cmds.c 8 Jun 2004 08:44:04 -0000 1.112
-+++ src/dird/ua_cmds.c 5 Aug 2004 19:58:51 -0000
-@@ -682,7 +682,7 @@
-
- static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
- {
-- char ed1[50];
-+ char ed1[150];
- POOLMEM *query;
- if (!duration_to_utime(val, &mr->VolRetention)) {
- bsendmsg(ua, _("Invalid retention period specified: %s\n"), val);
-@@ -694,7 +694,7 @@
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
-- bsendmsg(ua, _("New retention seconds is: %s\n"),
-+ bsendmsg(ua, _("New retention period is: %s\n"),
- edit_utime(mr->VolRetention, ed1));
- }
- free_pool_memory(query);
-@@ -702,7 +702,7 @@
-
- static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
- {
-- char ed1[50];
-+ char ed1[150];
- POOLMEM *query;
-
- if (!duration_to_utime(val, &mr->VolUseDuration)) {
-@@ -851,7 +851,7 @@
- MEDIA_DBR mr;
- POOL_DBR pr;
- POOLMEM *query;
-- char ed1[30];
-+ char ed1[130];
- bool done = false;
- char *kw[] = {
- N_("VolStatus"), /* 0 */
-@@ -943,7 +943,7 @@
- update_volstatus(ua, ua->cmd, &mr);
- break;
- case 1: /* Retention */
-- bsendmsg(ua, _("Current retention seconds is: %s\n"),
-+ bsendmsg(ua, _("Current retention period is: %s\n"),
- edit_utime(mr.VolRetention, ed1));
- if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
- return 0;
-Index: src/dird/ua_select.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-retrieving revision 1.50
-diff -u -r1.50 ua_select.c
---- src/dird/ua_select.c 5 Jun 2004 10:15:55 -0000 1.50
-+++ src/dird/ua_select.c 5 Aug 2004 19:58:52 -0000
-@@ -38,7 +38,7 @@
- */
- int confirm_retention(UAContext *ua, utime_t *ret, char *msg)
- {
-- char ed1[30];
-+ char ed1[130];
-
- for ( ;; ) {
- bsendmsg(ua, _("The current %s retention period is: %s\n"),
-Index: src/lib/edit.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/lib/edit.c,v
-retrieving revision 1.17
-diff -u -r1.17 edit.c
---- src/lib/edit.c 10 Jun 2004 09:45:41 -0000 1.17
-+++ src/lib/edit.c 5 Aug 2004 19:58:54 -0000
-@@ -3,7 +3,7 @@
- *
- * Kern Sibbald, December MMII
- *
-- * Version $Id$
-+ * Version $Id$
- */
-
- /*
-@@ -77,7 +77,6 @@
- }
-
-
--
- /*
- * Edit an integer number with commas, the supplied buffer
- * must be at least 27 bytes long. The incoming number
-@@ -85,7 +84,21 @@
- */
- char *edit_uint64_with_commas(uint64_t val, char *buf)
- {
-- sprintf(buf, "%" llu, val);
-+ /*
-+ * Replacement for sprintf(buf, "%" llu, val)
-+ */
-+ char mbuf[50];
-+ mbuf[sizeof(mbuf)-1] = 0;
-+ int i = sizeof(mbuf)-2; /* edit backward */
-+ if (val == 0) {
-+ mbuf[i--] = '0';
-+ } else {
-+ while (val != 0) {
-+ mbuf[i--] = "0123456789"[val%10];
-+ val /= 10;
-+ }
-+ }
-+ strcpy(buf, &mbuf[i+1]);
- return add_commas(buf, buf);
- }
-
-@@ -96,7 +109,21 @@
- */
- char *edit_uint64(uint64_t val, char *buf)
- {
-- sprintf(buf, "%" llu, val);
-+ /*
-+ * Replacement for sprintf(buf, "%" llu, val)
-+ */
-+ char mbuf[50];
-+ mbuf[sizeof(mbuf)-1] = 0;
-+ int i = sizeof(mbuf)-2; /* edit backward */
-+ if (val == 0) {
-+ mbuf[i--] = '0';
-+ } else {
-+ while (val != 0) {
-+ mbuf[i--] = "0123456789"[val%10];
-+ val /= 10;
-+ }
-+ }
-+ strcpy(buf, &mbuf[i+1]);
- return buf;
- }
-
-@@ -104,9 +131,10 @@
- * Given a string "str", separate the integer part into
- * str, and the modifier into mod.
- */
--static bool get_modifier(char *str, char *mod, int mod_len)
-+static bool get_modifier(char *str, char *num, int num_len, char *mod, int mod_len)
- {
-- int i, len;
-+ int i, len, num_begin, num_end, mod_begin, mod_end;
-+
- /*
- * Look for modifier by walking back looking for the first
- * space or digit.
-@@ -114,36 +142,50 @@
- strip_trailing_junk(str);
- len = strlen(str);
-
-- /* Find beginning of the modifier */
-- for (i=len; i > 0; i--) {
-- if (!B_ISALPHA(str[i-1])) {
-+ for (i=0; i<len; i++) {
-+ if (!B_ISSPACE(str[i])) {
- break;
- }
- }
-+ num_begin = i;
-
-- /* If nothing found, error */
-- if (i == 0) {
-- Dmsg2(200, "error i=%d len=%d\n", i, len);
-+ /* Walk through integer part */
-+ for ( ; i<len; i++) {
-+ if (!B_ISDIGIT(str[i])) {
-+ break;
-+ }
-+ }
-+ num_end = i;
-+ if (num_len > (num_end - num_begin + 1)) {
-+ num_len = num_end - num_begin + 1;
-+ }
-+ if (num_len == 0) {
- return false;
- }
--
-- /* Move modifier to its location */
-- bstrncpy(mod, &str[i], mod_len);
-- Dmsg2(200, "in=%s mod=%s:\n", str, mod);
--
-- /* Backup over any spaces in front of modifier */
-- for ( ; i > 0; i--) {
-- if (B_ISSPACE(str[i-1])) {
-- continue;
-+ for ( ; i<len; i++) {
-+ if (!B_ISSPACE(str[i])) {
-+ break;
-+ }
-+ }
-+ mod_begin = i;
-+ for ( ; i<len; i++) {
-+ if (!B_ISALPHA(str[i])) {
-+ break;
- }
-- str[i] = 0;
-- break;
- }
-- /* The remainder (beginning) should be our number */
-- if (!is_a_number(str)) {
-- Dmsg0(200, "input not a number\n");
-+ mod_end = i;
-+ if (mod_len > (mod_end - mod_begin + 1)) {
-+ mod_len = mod_end - mod_begin + 1;
-+ }
-+ Dmsg5(900, "str=%s: num_beg=%d num_end=%d mod_beg=%d mod_end=%d\n",
-+ str, num_begin, num_end, mod_begin, mod_end);
-+ bstrncpy(num, &str[num_begin], num_len);
-+ bstrncpy(mod, &str[mod_begin], mod_len);
-+ if (!is_a_number(num)) {
- return false;
- }
-+ bstrncpy(str, &str[mod_end], len);
-+
- return true;
- }
-
-@@ -155,8 +197,9 @@
- int duration_to_utime(char *str, utime_t *value)
- {
- int i, mod_len;
-- double val;
-+ double val, total = 0.0;
- char mod_str[20];
-+ char num_str[50];
- /*
- * The "n" = mins and months appears before minutes so that m maps
- * to months. These "kludges" make it compatible with pre 1.31
-@@ -167,26 +210,33 @@
- static const int32_t mult[] = {60, 1, 60*60*24*30, 60,
- 60*60, 60*60*24, 60*60*24*7, 60*60*24*91, 60*60*24*365};
-
-- if (!get_modifier(str, mod_str, sizeof(mod_str))) {
-- return 0;
-- }
-- /* Now find the multiplier corresponding to the modifier */
-- mod_len = strlen(mod_str);
-- for (i=0; mod[i]; i++) {
-- if (strncasecmp(mod_str, mod[i], mod_len) == 0) {
-- break;
-+ while (*str) {
-+ if (!get_modifier(str, num_str, sizeof(num_str), mod_str, sizeof(mod_str))) {
-+ return 0;
-+ }
-+ /* Now find the multiplier corresponding to the modifier */
-+ mod_len = strlen(mod_str);
-+ if (mod_len == 0) {
-+ i = 1; /* assume seconds */
-+ } else {
-+ for (i=0; mod[i]; i++) {
-+ if (strncasecmp(mod_str, mod[i], mod_len) == 0) {
-+ break;
-+ }
-+ }
-+ if (mod[i] == NULL) {
-+ i = 1; /* no modifier, assume secs */
-+ }
-+ }
-+ Dmsg2(900, "str=%s: mult=%d\n", num_str, mult[i]);
-+ errno = 0;
-+ val = strtod(num_str, NULL);
-+ if (errno != 0 || val < 0) {
-+ return 0;
- }
-+ total += val * mult[i];
- }
-- if (mod[i] == NULL) {
-- i = 1; /* no modifier, assume 1 */
-- }
-- Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]);
-- errno = 0;
-- val = strtod(str, NULL);
-- if (errno != 0 || val < 0) {
-- return 0;
-- }
-- *value = (utime_t)(val * mult[i]);
-+ *value = (utime_t)total;
- return 1;
- }
-
-@@ -195,32 +245,33 @@
- */
- char *edit_utime(utime_t val, char *buf)
- {
-- char mybuf[30];
-+ char mybuf[200];
- static const int32_t mult[] = {60*60*24*365, 60*60*24*30, 60*60*24, 60*60, 60};
- static const char *mod[] = {"year", "month", "day", "hour", "min"};
- int i;
- uint32_t times;
-+ int buf_len = 50;
-
- *buf = 0;
- for (i=0; i<5; i++) {
- times = (uint32_t)(val / mult[i]);
- if (times > 0) {
- val = val - (utime_t)times * mult[i];
-- sprintf(mybuf, "%d %s%s ", times, mod[i], times>1?"s":"");
-- strcat(buf, mybuf);
-+ bsnprintf(mybuf, sizeof(mybuf), "%d %s%s ", times, mod[i], times>1?"s":"");
-+ bstrncat(buf, mybuf, buf_len);
- }
- }
- if (val == 0 && strlen(buf) == 0) {
-- strcat(buf, "0 secs");
-+ bstrncat(buf, "0 secs", buf_len);
- } else if (val != 0) {
-- sprintf(mybuf, "%d sec%s", (uint32_t)val, val>1?"s":"");
-- strcat(buf, mybuf);
-+ bsnprintf(mybuf, sizeof(mybuf), "%d sec%s", (uint32_t)val, val>1?"s":"");
-+ bstrncat(buf, mybuf, buf_len);
- }
- return buf;
- }
-
- /*
-- * Convert a size size in bytes to uint64_t
-+ * Convert a size in bytes to uint64_t
- * Returns 0: if error
- 1: if OK, and value stored in value
- */
-@@ -229,6 +280,7 @@
- int i, mod_len;
- double val;
- char mod_str[20];
-+ char num_str[50];
- static const char *mod[] = {"*", "k", "kb", "m", "mb", "g", "gb", NULL}; /* first item * not used */
- const int64_t mult[] = {1, /* byte */
- 1024, /* kilobyte */
-@@ -238,7 +290,7 @@
- 1073741824, /* gigabyte */
- 1000000000}; /* gb gigabyte */
-
-- if (!get_modifier(str, mod_str, sizeof(mod_str))) {
-+ if (!get_modifier(str, num_str, sizeof(num_str), mod_str, sizeof(mod_str))) {
- return 0;
- }
- /* Now find the multiplier corresponding to the modifier */
-@@ -251,9 +303,9 @@
- if (mod[i] == NULL) {
- i = 0; /* no modifier found, assume 1 */
- }
-- Dmsg2(200, "str=%s: mult=%d\n", str, mult[i]);
-+ Dmsg2(900, "str=%s: mult=%d\n", str, mult[i]);
- errno = 0;
-- val = strtod(str, NULL);
-+ val = strtod(num_str, NULL);
- if (errno != 0 || val < 0) {
- return 0;
- }
-@@ -265,7 +317,7 @@
- * Check if specified string is a number or not.
- * Taken from SQLite, cool, thanks.
- */
--int is_a_number(const char *n)
-+bool is_a_number(const char *n)
- {
- bool digit_seen = false;
-
-@@ -291,7 +343,7 @@
- /*
- * Check if the specified string is an integer
- */
--int is_an_integer(const char *n)
-+bool is_an_integer(const char *n)
- {
- bool digit_seen = false;
- while (B_ISDIGIT(*n)) {
-Index: src/lib/protos.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/lib/protos.h,v
-retrieving revision 1.77
-diff -u -r1.77 protos.h
---- src/lib/protos.h 12 Jun 2004 07:51:26 -0000 1.77
-+++ src/lib/protos.h 5 Aug 2004 19:58:54 -0000
-@@ -26,99 +26,99 @@
- struct JCR;
-
- /* attr.c */
--ATTR *new_attr();
--void free_attr(ATTR *attr);
--int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr);
--void build_attr_output_fnames(JCR *jcr, ATTR *attr);
--void print_ls_output(JCR *jcr, ATTR *attr);
-+ATTR *new_attr();
-+void free_attr(ATTR *attr);
-+int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr);
-+void build_attr_output_fnames(JCR *jcr, ATTR *attr);
-+void print_ls_output(JCR *jcr, ATTR *attr);
-
- /* base64.c */
--void base64_init (void);
--int to_base64 (intmax_t value, char *where);
--int from_base64 (intmax_t *value, char *where);
--int bin_to_base64 (char *buf, char *bin, int len);
-+void base64_init (void);
-+int to_base64 (intmax_t value, char *where);
-+int from_base64 (intmax_t *value, char *where);
-+int bin_to_base64 (char *buf, char *bin, int len);
-
- /* bsys.c */
--char *bstrncpy (char *dest, const char *src, int maxlen);
--char *bstrncat (char *dest, const char *src, int maxlen);
--void *b_malloc (const char *file, int line, size_t size);
-+char *bstrncpy (char *dest, const char *src, int maxlen);
-+char *bstrncat (char *dest, const char *src, int maxlen);
-+void *b_malloc (const char *file, int line, size_t size);
- #ifndef DEBUG
--void *bmalloc (size_t size);
-+void *bmalloc (size_t size);
- #endif
--void *brealloc (void *buf, size_t size);
--void *bcalloc (size_t size1, size_t size2);
--int bsnprintf (char *str, int32_t size, const char *format, ...);
--int bvsnprintf (char *str, int32_t size, const char *format, va_list ap);
--int pool_sprintf (char *pool_buf, const char *fmt, ...);
--void create_pid_file (char *dir, const char *progname, int port);
--int delete_pid_file (char *dir, const char *progname, int port);
--void drop (char *uid, char *gid);
--int bmicrosleep (time_t sec, long usec);
--char *bfgets (char *s, int size, FILE *fd);
--void make_unique_filename (POOLMEM **name, int Id, char *what);
-+void *brealloc (void *buf, size_t size);
-+void *bcalloc (size_t size1, size_t size2);
-+int bsnprintf (char *str, int32_t size, const char *format, ...);
-+int bvsnprintf (char *str, int32_t size, const char *format, va_list ap);
-+int pool_sprintf (char *pool_buf, const char *fmt, ...);
-+void create_pid_file (char *dir, const char *progname, int port);
-+int delete_pid_file (char *dir, const char *progname, int port);
-+void drop (char *uid, char *gid);
-+int bmicrosleep (time_t sec, long usec);
-+char *bfgets (char *s, int size, FILE *fd);
-+void make_unique_filename (POOLMEM **name, int Id, char *what);
- #ifndef HAVE_STRTOLL
--long long int strtoll (const char *ptr, char **endptr, int base);
-+long long int strtoll (const char *ptr, char **endptr, int base);
- #endif
- void read_state_file(char *dir, const char *progname, int port);
-
- /* bnet.c */
--int32_t bnet_recv (BSOCK *bsock);
--int bnet_send (BSOCK *bsock);
--int bnet_fsend (BSOCK *bs, const char *fmt, ...);
--int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
--int bnet_sig (BSOCK *bs, int sig);
--int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
--int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need);
--BSOCK * bnet_connect (JCR *jcr, int retry_interval,
-- int max_retry_time, const char *name, char *host, char *service,
-- int port, int verbose);
--void bnet_close (BSOCK *bsock);
--BSOCK * init_bsock (JCR *jcr, int sockfd, const char *who, char *ip,
-- int port, struct sockaddr_in *client_addr);
--BSOCK * dup_bsock (BSOCK *bsock);
--void term_bsock (BSOCK *bsock);
--char * bnet_strerror (BSOCK *bsock);
--char * bnet_sig_to_ascii (BSOCK *bsock);
--int bnet_wait_data (BSOCK *bsock, int sec);
--int bnet_wait_data_intr (BSOCK *bsock, int sec);
--int bnet_despool_to_bsock (BSOCK *bsock, void update(ssize_t size), ssize_t size);
--int is_bnet_stop (BSOCK *bsock);
--int is_bnet_error (BSOCK *bsock);
--void bnet_suppress_error_messages(BSOCK *bsock, bool flag);
-+int32_t bnet_recv (BSOCK *bsock);
-+int bnet_send (BSOCK *bsock);
-+int bnet_fsend (BSOCK *bs, const char *fmt, ...);
-+int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
-+int bnet_sig (BSOCK *bs, int sig);
-+int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
-+int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need);
-+BSOCK * bnet_connect (JCR *jcr, int retry_interval,
-+ int max_retry_time, const char *name, char *host, char *service,
-+ int port, int verbose);
-+void bnet_close (BSOCK *bsock);
-+BSOCK * init_bsock (JCR *jcr, int sockfd, const char *who, char *ip,
-+ int port, struct sockaddr_in *client_addr);
-+BSOCK * dup_bsock (BSOCK *bsock);
-+void term_bsock (BSOCK *bsock);
-+char * bnet_strerror (BSOCK *bsock);
-+char * bnet_sig_to_ascii (BSOCK *bsock);
-+int bnet_wait_data (BSOCK *bsock, int sec);
-+int bnet_wait_data_intr (BSOCK *bsock, int sec);
-+int bnet_despool_to_bsock (BSOCK *bsock, void update(ssize_t size), ssize_t size);
-+int is_bnet_stop (BSOCK *bsock);
-+int is_bnet_error (BSOCK *bsock);
-+void bnet_suppress_error_messages(BSOCK *bsock, bool flag);
-
- /* bget_msg.c */
--int bget_msg(BSOCK *sock);
-+int bget_msg(BSOCK *sock);
-
- /* bpipe.c */
--BPIPE * open_bpipe(char *prog, int wait, const char *mode);
--int close_wpipe(BPIPE *bpipe);
--int close_bpipe(BPIPE *bpipe);
-+BPIPE * open_bpipe(char *prog, int wait, const char *mode);
-+int close_wpipe(BPIPE *bpipe);
-+int close_bpipe(BPIPE *bpipe);
-
- /* cram-md5.c */
- int cram_md5_get_auth(BSOCK *bs, char *password, int ssl_need);
- int cram_md5_auth(BSOCK *bs, char *password, int ssl_need);
- void hmac_md5(uint8_t* text, int text_len, uint8_t* key,
-- int key_len, uint8_t *hmac);
-+ int key_len, uint8_t *hmac);
-
- /* crc32.c */
-
- uint32_t bcrc32(uint8_t *buf, int len);
-
- /* daemon.c */
--void daemon_start ();
-+void daemon_start ();
-
- /* edit.c */
--uint64_t str_to_uint64(char *str);
--int64_t str_to_int64(char *str);
--char * edit_uint64_with_commas (uint64_t val, char *buf);
--char * add_commas (char *val, char *buf);
--char * edit_uint64 (uint64_t val, char *buf);
--int duration_to_utime (char *str, utime_t *value);
--int size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
--char *edit_utime (utime_t val, char *buf);
--int is_a_number (const char *num);
--int is_an_integer (const char *n);
--bool is_name_valid (char *name, POOLMEM **msg);
-+uint64_t str_to_uint64(char *str);
-+int64_t str_to_int64(char *str);
-+char * edit_uint64_with_commas (uint64_t val, char *buf);
-+char * add_commas (char *val, char *buf);
-+char * edit_uint64 (uint64_t val, char *buf);
-+int duration_to_utime (char *str, utime_t *value);
-+int size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
-+char *edit_utime (utime_t val, char *buf);
-+bool is_a_number (const char *num);
-+bool is_an_integer (const char *n);
-+bool is_name_valid (char *name, POOLMEM **msg);
-
- /* jcr.c (most definitions are in src/jcr.h) */
- void init_last_jobs_list();
-@@ -132,36 +132,36 @@
-
-
- /* lex.c */
--LEX * lex_close_file (LEX *lf);
--LEX * lex_open_file (LEX *lf, const char *fname, LEX_ERROR_HANDLER *scan_error);
--int lex_get_char (LEX *lf);
--void lex_unget_char (LEX *lf);
--const char * lex_tok_to_str (int token);
--int lex_get_token (LEX *lf, int expect);
-+LEX * lex_close_file (LEX *lf);
-+LEX * lex_open_file (LEX *lf, const char *fname, LEX_ERROR_HANDLER *scan_error);
-+int lex_get_char (LEX *lf);
-+void lex_unget_char (LEX *lf);
-+const char * lex_tok_to_str (int token);
-+int lex_get_token (LEX *lf, int expect);
-
- /* message.c */
--void my_name_is (int argc, char *argv[], const char *name);
--void init_msg (JCR *jcr, MSGS *msg);
--void term_msg (void);
--void close_msg (JCR *jcr);
--void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code);
--void rem_msg_dest (MSGS *msg, int dest, int type, char *where);
--void Jmsg (JCR *jcr, int type, int level, const char *fmt, ...);
--void dispatch_message (JCR *jcr, int type, int level, char *buf);
--void init_console_msg (char *wd);
--void free_msgs_res (MSGS *msgs);
--void dequeue_messages (JCR *jcr);
--void set_trace (int trace_flag);
--void set_exit_on_error (int value);
-+void my_name_is (int argc, char *argv[], const char *name);
-+void init_msg (JCR *jcr, MSGS *msg);
-+void term_msg (void);
-+void close_msg (JCR *jcr);
-+void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code);
-+void rem_msg_dest (MSGS *msg, int dest, int type, char *where);
-+void Jmsg (JCR *jcr, int type, int level, const char *fmt, ...);
-+void dispatch_message (JCR *jcr, int type, int level, char *buf);
-+void init_console_msg (char *wd);
-+void free_msgs_res (MSGS *msgs);
-+void dequeue_messages (JCR *jcr);
-+void set_trace (int trace_flag);
-+void set_exit_on_error (int value);
-
- /* bnet_server.c */
--void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq,
-- void *handle_client_request(void *bsock));
--void bnet_stop_thread_server(pthread_t tid);
--void bnet_server (int port, void handle_client_request(BSOCK *bsock));
--int net_connect (int port);
--BSOCK * bnet_bind (int port);
--BSOCK * bnet_accept (BSOCK *bsock, char *who);
-+void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq,
-+ void *handle_client_request(void *bsock));
-+void bnet_stop_thread_server(pthread_t tid);
-+void bnet_server (int port, void handle_client_request(BSOCK *bsock));
-+int net_connect (int port);
-+BSOCK * bnet_bind (int port);
-+BSOCK * bnet_accept (BSOCK *bsock, char *who);
-
- /* idcache.c */
- char *getuser(uid_t uid);
-@@ -171,41 +171,41 @@
-
-
- /* signal.c */
--void init_signals (void terminate(int sig));
--void init_stack_dump (void);
-+void init_signals (void terminate(int sig));
-+void init_stack_dump (void);
-
- /* scan.c */
--void strip_trailing_junk (char *str);
--void strip_trailing_slashes (char *dir);
--bool skip_spaces (char **msg);
--bool skip_nonspaces (char **msg);
--int fstrsch (char *a, char *b);
--char *next_arg(char **s);
--int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
-- char **argk, char **argv, int max_args);
--void split_path_and_filename(const char *fname, POOLMEM **path,
-- int *pnl, POOLMEM **file, int *fnl);
--int bsscanf(const char *buf, const char *fmt, ...);
-+void strip_trailing_junk (char *str);
-+void strip_trailing_slashes (char *dir);
-+bool skip_spaces (char **msg);
-+bool skip_nonspaces (char **msg);
-+int fstrsch (char *a, char *b);
-+char *next_arg(char **s);
-+int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
-+ char **argk, char **argv, int max_args);
-+void split_path_and_filename(const char *fname, POOLMEM **path,
-+ int *pnl, POOLMEM **file, int *fnl);
-+int bsscanf(const char *buf, const char *fmt, ...);
-
-
- /* util.c */
--int is_buf_zero (char *buf, int len);
--void lcase (char *str);
--void bash_spaces (char *str);
--void unbash_spaces (char *str);
--char * encode_time (time_t time, char *buf);
--char * encode_mode (mode_t mode, char *buf);
--int do_shell_expansion (char *name, int name_len);
--void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen);
--int pm_strcat (POOLMEM **pm, const char *str);
--int pm_strcpy (POOLMEM **pm, const char *str);
--int run_program (char *prog, int wait, POOLMEM *results);
--char * job_type_to_str (int type);
--char * job_status_to_str (int stat);
--char * job_level_to_str (int level);
--void make_session_key (char *key, char *seed, int mode);
--POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to);
--void set_working_directory(char *wd);
-+int is_buf_zero (char *buf, int len);
-+void lcase (char *str);
-+void bash_spaces (char *str);
-+void unbash_spaces (char *str);
-+char * encode_time (time_t time, char *buf);
-+char * encode_mode (mode_t mode, char *buf);
-+int do_shell_expansion (char *name, int name_len);
-+void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen);
-+int pm_strcat (POOLMEM **pm, const char *str);
-+int pm_strcpy (POOLMEM **pm, const char *str);
-+int run_program (char *prog, int wait, POOLMEM *results);
-+char * job_type_to_str (int type);
-+char * job_status_to_str (int stat);
-+char * job_level_to_str (int level);
-+void make_session_key (char *key, char *seed, int mode);
-+POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, const char *to);
-+void set_working_directory(char *wd);
-
-
- /* watchdog.c */
+++ /dev/null
-
- This patch fixes a problem where the Options are not properly passed
- from the last Option group to the NULL option group -- i.e. some of
- the files do not get the correct options.
-
- Apply to Bacula 1.34.6 with:
-
- cd <bacula-source>
- patch -p0 <1.34.6-find.patch
- make
- ...
-
-Index: src/findlib/find.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/findlib/find.c,v
-retrieving revision 1.18
-diff -u -r1.18 find.c
---- src/findlib/find.c 9 Jun 2004 11:52:24 -0000 1.18
-+++ src/findlib/find.c 6 Aug 2004 13:25:52 -0000
-@@ -160,10 +160,10 @@
-
- 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;
- for (k=0; k<fo->wild.size(); k++) {
- if (fnmatch((char *)fo->wild.get(k), ff->fname, 0) == 0) {
-- ff->flags = fo->flags;
-- ff->GZIP_level = fo->GZIP_level;
- if (ff->flags & FO_EXCLUDE) {
- return false; /* reject file */
- }
-@@ -205,7 +205,6 @@
- case FT_NOFOLLOW:
- case FT_NOSTAT:
- case FT_NOCHG:
-- case FT_DIRNOCHG:
- case FT_ISARCH:
- case FT_NORECURSE:
- case FT_NOFSCHG:
-@@ -222,6 +221,7 @@
- case FT_RAW:
- case FT_FIFO:
- case FT_SPEC:
-+ case FT_DIRNOCHG:
- if (accept_file(ff)) {
- return ff->callback(ff, hpkt);
- } else {
+++ /dev/null
---- Makefile.in 2004-07-29 15:29:56.000000000 -0400
-+++ gnome-console-Makefile.in 2004-08-01 14:22:04.000000000 -0400
-@@ -12,7 +12,7 @@
- # top dir
- topdir = ../..
- # this dir relative to top dir
--thisdir = src/gnome2-console
-+thisdir = src/gnome-console
-
- DEBUG=@DEBUG@
-
-@@ -26,10 +26,9 @@
-
-
- #
--CONSSRCS = console.c console_conf.c authenticate.c support.c interface.c callbacks.c \
-- restore.c
--CONSOBJS = console.o console_conf.o authenticate.o support.o interface.o callbacks.o \
-- restore.o
-+CONSSRCS = console.c console_conf.c authenticate.c support.c interface.c callbacks.c
-+
-+CONSOBJS = console.o console_conf.o authenticate.o support.o interface.o callbacks.o
-
- # these are the objects that are changed by the .configure process
- EXTRAOBJS = @OBJLIST@
+++ /dev/null
-
-This patch fixes two bugs:
-1. It ignores an device open failure if polling.
-2. It disables the insanity check on reading the
- tape label while polling. Normally the check
- doesn't allow the label to be read more than 100
- times.
-
-Apply the patch to version 1.34.6 (possibly earlier versions) with:
-
- cd <bacula-source>
- patch -p0 <1.34.6-poll.patch
- make
- ...
-
-Index: src/stored/label.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/label.c,v
-retrieving revision 1.42.2.1
-diff -u -r1.42.2.1 label.c
---- src/stored/label.c 20 Jun 2004 11:43:04 -0000 1.42.2.1
-+++ src/stored/label.c 2 Sep 2004 12:21:00 -0000
-@@ -74,8 +74,8 @@
- * Cancel Job if too many label errors
- * => we are in a loop
- */
-- if (jcr->label_errors++ > 100) {
-- Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
-+ if (!dev->poll && jcr->label_errors++ > 100) {
-+ Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
- }
- return jcr->label_status = VOL_NAME_ERROR;
- }
-@@ -157,8 +157,8 @@
- * Cancel Job if too many label errors
- * => we are in a loop
- */
-- if (jcr->label_errors++ > 100) {
-- Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
-+ if (!dev->poll && jcr->label_errors++ > 100) {
-+ Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
- }
- return jcr->label_status = VOL_NAME_ERROR;
- }
-Index: src/stored/mount.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/mount.c,v
-retrieving revision 1.59.2.1
-diff -u -r1.59.2.1 mount.c
---- src/stored/mount.c 20 Jun 2004 11:43:04 -0000 1.59.2.1
-+++ src/stored/mount.c 2 Sep 2004 12:21:00 -0000
-@@ -154,7 +154,11 @@
-
- /* Ensure the device is open */
- if (!open_device(jcr, dev)) {
-- return 0;
-+ if (dev->poll) {
-+ goto mount_next_vol;
-+ } else {
-+ return 0;
-+ }
- }
-
- /*
+++ /dev/null
-
- This patch fixes a bug where Inc, Diff, and Full Pool overrides
- would incorrectly override a Pool= on the Run card. The patch
- also includes the Pool actually used in the Job Report.
-
- Apply the patch to version 1.34.6 with:
-
- cd <bacula-source>
- patch -p0 <1.34.6-pool.patch
- make
- ...
-
-Index: src/dird/scheduler.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/scheduler.c,v
-retrieving revision 1.24
-diff -u -r1.24 scheduler.c
---- src/dird/scheduler.c 13 Mar 2004 09:30:10 -0000 1.24
-+++ src/dird/scheduler.c 11 Aug 2004 07:38:51 -0000
-@@ -147,15 +147,6 @@
- if (run->pool) {
- jcr->pool = run->pool; /* override pool */
- }
-- if (run->full_pool) {
-- jcr->pool = run->full_pool; /* override full pool */
-- }
-- if (run->inc_pool) {
-- jcr->pool = run->inc_pool; /* override inc pool */
-- }
-- if (run->dif_pool) {
-- jcr->pool = run->dif_pool; /* override dif pool */
-- }
- if (run->storage) {
- jcr->store = run->storage; /* override storage */
- }
-Index: src/dird/backup.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/backup.c,v
-retrieving revision 1.65
-diff -u -r1.65 backup.c
---- src/dird/backup.c 19 Apr 2004 14:27:00 -0000 1.65
-+++ src/dird/backup.c 11 Aug 2004 07:38:52 -0000
-@@ -468,6 +468,7 @@
- Backup Level: %s%s\n\
- Client: %s\n\
- FileSet: \"%s\" %s\n\
-+Pool: \"%s\"\n\
- Start time: %s\n\
- End time: %s\n\
- FD Files Written: %s\n\
-@@ -491,6 +492,7 @@
- level_to_str(jcr->JobLevel), since,
- jcr->client->hdr.name,
- jcr->fileset->hdr.name, fsr->cCreateTime,
-+ jcr->pool->hdr.name,
- sdt,
- edt,
- edit_uint64_with_commas(jcr->jr.JobFiles, ec1),
+++ /dev/null
-
- This patch fixes two bugs in the job queue scheduling:
- 1. It clears the SD status when rescheduling a job so that
- the correct status will be displayed by the Director.
- 2. When starting a reschedule thread, it decrements the jcr
- use_count so that the job will not become a zombie.
-
- Apply it to 1.34.6 (possibly to earlier versions with):
-
- cd <bacula-source>
- patch -p0 <1.34.6-resched.patch
- make
- ...
-
-Index: src/dird/jobq.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/jobq.c,v
-retrieving revision 1.19
-diff -u -r1.19 jobq.c
---- src/dird/jobq.c 1 Jun 2004 20:10:04 -0000 1.19
-+++ src/dird/jobq.c 1 Sep 2004 17:22:51 -0000
-@@ -160,11 +160,11 @@
- Dmsg0(300, "Enter sched_wait.\n");
- free(arg);
- time_t wtime = jcr->sched_time - time(NULL);
-+ set_jcr_job_status(jcr, JS_WaitStartTime);
- /* Wait until scheduled time arrives */
- if (wtime > 0 && verbose) {
- Jmsg(jcr, M_INFO, 0, _("Job %s waiting %d seconds for scheduled start time.\n"),
- jcr->Job, wtime);
-- set_jcr_job_status(jcr, JS_WaitStartTime);
- }
- /* Check every 30 seconds if canceled */
- while (wtime > 0) {
-@@ -217,10 +217,10 @@
- sched_pkt = (wait_pkt *)malloc(sizeof(wait_pkt));
- sched_pkt->jcr = jcr;
- sched_pkt->jq = jq;
-+ jcr->use_count--; /* release our use of jcr */
- stat = pthread_create(&id, &jq->attr, sched_wait, (void *)sched_pkt);
- if (stat != 0) { /* thread not created */
- Jmsg1(jcr, M_ERROR, 0, "pthread_thread_create: ERR=%s\n", strerror(stat));
-- jcr->use_count--; /* release jcr */
- }
- return stat;
- }
-@@ -465,6 +465,7 @@
- Dmsg2(300, "Rescheduled Job %s to re-run in %d seconds.\n", jcr->Job,
- (int)jcr->job->RescheduleInterval);
- jcr->JobStatus = JS_Created; /* force new status */
-+ jcr->SDJobStatus = 0;
- dird_free_jcr(jcr); /* partial cleanup old stuff */
- if (jcr->JobBytes == 0) {
- Dmsg1(300, "Requeue job=%d\n", jcr->JobId);
-@@ -501,8 +502,10 @@
- jcr->db = NULL;
- }
- Dmsg1(300, "====== Termination job=%d\n", jcr->JobId);
-+ V(jq->mutex); /* release internal job queue lock */
- free_jcr(jcr);
- free(je); /* release job entry */
-+ P(jq->mutex); /* acquire internal job queue lock */
- }
- /*
- * If any job in the wait queue can be run,
+++ /dev/null
-
- This patch eliminates unwanted output (some 5000 lines) when doing
- an "update slots" command.
- Apply to version 1.34.6 with:
-
- cd <bacula-source>
- patch -p0 <1.34.6-slots.patch
- make
- ...
-
-Index: src/dird/ua_label.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_label.c,v
-retrieving revision 1.34
-diff -u -r1.34 ua_label.c
---- src/dird/ua_label.c 10 Jun 2004 13:08:01 -0000 1.34
-+++ src/dird/ua_label.c 5 Aug 2004 20:05:27 -0000
-@@ -255,7 +255,6 @@
- db_lock(ua->db);
- db_make_inchanger_unique(ua->jcr, ua->db, &mr);
- db_unlock(ua->db);
-- bsendmsg(ua, _("No VolName for Slot=%d set InChanger to zero.\n"), i);
- }
- }
-
+++ /dev/null
-
-Note: the patches listed here are not in their order of creation.
-
-1.34.6-block.patch:
- In some cases, Bacula will get an error
- on a tape and not be able to write and EOF mark. In this
- case, the tape will no longer be readable. When this happens,
- Bacula tries to plunge on but gets into lots of trouble.
- This patch should fix that by immediately marking the Job
- in error, and by avoiding running through code that doesn't
- make any sense after a fatal error.
-
-1.34.6-deadlock.patch:
- This patch fixes two problems: 1. A deadlock between the job
- queue scheduler and the watchdog thread. 2. A bad initialization
- of the watchdog queue which could cause memory corruption. It also
- reduces the watchdog granularity from 1 second to 10 seconds.
-
-1.34.6-duration.patch:
- Patch to allow more natural input of time durations.
- Permitted form is "1 day 2 hours 5 sec" with and without
- spaces. The different duration specifications (day, hour, ...)
- can be in any order.
-
-1.34.6-find.patch:
- This patch fixes a problem where the Options are not properly passed
- from the last Option group to the NULL option group -- i.e. some of
- the files do not get the correct options.
-
-1.34.6-gnome-console-Makefile.in.patch:
- This patch fixes an error in the Gnome 1.4 Makefile.
-
-1.34.6-poll.patch:
- This patch fixes two bugs:
- 1. It ignores an device open failure if polling.
- 2. It disables the insanity check on reading the
- tape label while polling. Normally the check
- doesn't allow the label to be read more than 100
- times.
-
-1.34.6-pool.patch:
- This patch fixes a bug where Inc, Diff, and Full Pool overrides
- would incorrectly override a Pool= on the Run card. The patch
- also includes the Pool actually used in the Job Report.
-
-1.34.6-resched.patch:
- This patch fixes two bugs in the job queue scheduling:
- 1. It clears the SD status when rescheduling a job so that
- the correct status will be displayed by the Director.
- 2. When starting a reschedule thread, it decrements the jcr
- use_count so that the job will not become a zombie.
-
-1.34.6-slots.patch:
- This patch eliminates unwanted output (some 5000 lines) when doing
- an "update slots" command.
-
-15Oct03
-1.34.6-ACL.patch:
- This patch fixes a bug where the enable_acl=yes flag was not
- being properly received by the File daemon.
-
+++ /dev/null
-
- This patch should fix a problem where the autochanger thinks
- a Volume is in the current magazine and loops a few times then
- gives up.
-
- Apply it to version 1.36.0 with the following:
-
- cd <bacula-source>
- patch -p0 <1.36.0-autochanger.patch
- make
- make install
-
-Index: src/stored/autochanger.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-retrieving revision 1.23
-diff -u -r1.23 autochanger.c
---- src/stored/autochanger.c 19 Sep 2004 18:56:27 -0000 1.23
-+++ src/stored/autochanger.c 21 Nov 2004 22:23:26 -0000
-@@ -52,10 +52,11 @@
- {
- JCR *jcr = dcr->jcr;
- DEVICE *dev = dcr->dev;
-- int slot = dcr->VolCatInfo.Slot;
-+ int slot;
- int drive = jcr->device->drive_index;
- int rtn_stat = -1; /* error status */
-
-+ slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
- /*
- * Handle autoloaders here. If we cannot autoload it, we
- * will return FALSE to ask the sysop.
-@@ -65,7 +66,7 @@
- return 0; /* For user, bail out right now */
- }
- if (dir_find_next_appendable_volume(dcr)) {
-- slot = dcr->VolCatInfo.Slot;
-+ slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
- } else {
- slot = 0;
- }
+++ /dev/null
-
- This patch fixes an autochanger problem where Bacula was trying
- to access a Volume that was not in the autochanger. You *must*
- also apply patch 1.36.0-autochanger.patch for this patch to work
- correctly. This patch will probably also correct some problems
- introduced with version 1.36 (dcrs) that make update slots
- fail.
-
- Apply it to 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-autochanger2.patch
- make
- make install
- ...
-
-Index: src/stored/dircmd.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/dircmd.c,v
-retrieving revision 1.79
-diff -u -r1.79 dircmd.c
---- src/stored/dircmd.c 21 Nov 2004 13:10:16 -0000 1.79
-+++ src/stored/dircmd.c 24 Nov 2004 11:46:45 -0000
-@@ -78,6 +78,7 @@
- static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
- char *newname, char *poolname,
- int Slot, int relabel);
-+static bool try_autoload_device(JCR *jcr, int slot, const char *VolName);
-
- struct s_cmds {
- const char *cmd;
-@@ -373,21 +374,11 @@
- DCR *dcr = jcr->dcr;
- int label_status;
-
-+ dcr->dev = dev;
- steal_device_lock(dev, &hold, BST_WRITING_LABEL);
-
-- bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName));
-- dcr->VolCatInfo.Slot = slot;
-- if (autoload_device(dcr, 0, dir) < 0) { /* autoload if possible */
-- goto bail_out;
-- }
--
-- /* Ensure that the device is open -- autoload_device() closes it */
-- for ( ; !(dev->state & ST_OPENED); ) {
-- if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
-- bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"),
-- dev_name(dev), strerror_dev(dev));
-- goto bail_out;
-- }
-+ if (!try_autoload_device(jcr, slot, newname)) {
-+ goto bail_out; /* error */
- }
-
- /* See what we have for a Volume */
-@@ -845,22 +836,12 @@
- BSOCK *dir = jcr->dir_bsock;
- bsteal_lock_t hold;
- DCR *dcr = jcr->dcr;
--
-+
-+ dcr->dev = dev;
- steal_device_lock(dev, &hold, BST_WRITING_LABEL);
-
-- dcr->VolumeName[0] = 0;
-- dcr->VolCatInfo.Slot = Slot;
-- if (autoload_device(dcr, 0, dir) < 0) { /* autoload if possible */
-- goto bail_out;
-- }
--
-- /* Ensure that the device is open -- autoload_device() closes it */
-- for ( ; !dev_state(dev, ST_OPENED); ) {
-- if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
-- bnet_fsend(dir, _("3910 Unable to open device \"%s\". ERR=%s\n"),
-- dev_name(dev), strerror_dev(dev));
-- goto bail_out;
-- }
-+ if (!try_autoload_device(jcr, Slot, "")) {
-+ goto bail_out; /* error */
- }
-
- dev->state &= ~ST_LABEL; /* force read of label */
-@@ -880,3 +861,27 @@
- give_back_device_lock(dev, &hold);
- return;
- }
-+
-+static bool try_autoload_device(JCR *jcr, int slot, const char *VolName)
-+{
-+ DCR *dcr = jcr->dcr;
-+ BSOCK *dir = jcr->dir_bsock;
-+ DEVICE *dev = dcr->dev;
-+
-+ bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
-+ dcr->VolCatInfo.Slot = slot;
-+ dcr->VolCatInfo.InChanger = slot > 0;
-+ if (autoload_device(dcr, 0, dir) < 0) { /* autoload if possible */
-+ return false;
-+ }
-+
-+ /* Ensure that the device is open -- autoload_device() closes it */
-+ for ( ; !(dev->state & ST_OPENED); ) {
-+ if (open_dev(dev, dcr->VolumeName, OPEN_READ_WRITE) < 0) {
-+ bnet_fsend(dir, _("3910 Unable to open device %s. ERR=%s\n"),
-+ dev_name(dev), strerror_dev(dev));
-+ return false;
-+ }
-+ }
-+ return true;
-+}
+++ /dev/null
-
- This patch fixes a bug in the FD when running with /lib/tls pthreads.
- Apply it to version 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-cancel.patch
- make
- make install
- ...
-
-Index: src/lib/jcr.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/lib/jcr.c,v
-retrieving revision 1.60
-diff -u -r1.60 jcr.c
---- src/lib/jcr.c 1 Sep 2004 19:44:29 -0000 1.60
-+++ src/lib/jcr.c 15 Nov 2004 11:32:46 -0000
-@@ -191,6 +191,7 @@
- Dmsg0(400, "Enter new_jcr\n");
- jcr = (JCR *)malloc(size);
- memset(jcr, 0, size);
-+ jcr->my_thread_id = pthread_self();
- jcr->msg_queue = New(dlist(item, &item->link));
- jcr->job_end_push.init(1, false);
- jcr->sched_time = time(NULL);
+++ /dev/null
-
- This patch fixes JobDefs so that if a Storage resource is
- specified in a Job, it is not overridden by the JobDefs.
- Apply to 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-jobdefs.patch
- make
- make install
- ...
-
-
-Index: src/dird/backup.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/backup.c,v
-retrieving revision 1.73
-diff -u -r1.73 backup.c
---- src/dird/backup.c 11 Nov 2004 07:55:05 -0000 1.73
-+++ src/dird/backup.c 11 Nov 2004 17:21:19 -0000
-@@ -448,6 +448,7 @@
- Client: %s\n\
- FileSet: \"%s\" %s\n\
- Pool: \"%s\"\n\
-+Storage: \"%s\"\n\
- Start time: %s\n\
- End time: %s\n\
- FD Files Written: %s\n\
-@@ -472,6 +473,7 @@
- jcr->client->hdr.name,
- jcr->fileset->hdr.name, fsr->cCreateTime,
- jcr->pool->hdr.name,
-+ jcr->store->hdr.name,
- sdt,
- edt,
- edit_uint64_with_commas(jcr->jr.JobFiles, ec1),
-Index: src/dird/dird.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/dird.c,v
-retrieving revision 1.70
-diff -u -r1.70 dird.c
---- src/dird/dird.c 22 Sep 2004 19:51:05 -0000 1.70
-+++ src/dird/dird.c 11 Nov 2004 17:21:19 -0000
-@@ -495,7 +495,7 @@
- /* Handle Storage alists specifically */
- JOB *jobdefs = job->jobdefs;
- for (i=0; i < MAX_STORE; i++) {
-- if (jobdefs->storage[i]) {
-+ if (jobdefs->storage[i] && !job->storage[i]) {
- STORE *st;
- job->storage[i] = New(alist(10, not_owned_by_alist));
- foreach_alist(st, jobdefs->storage[i]) {
+++ /dev/null
-
- This patch fixes a restore to permit specifying both a JobId and
- a filename or list of files to be restored. Apply to 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-jobid-restore.patch
- make
- make install
- ...
-
-Index: src/dird/sql_cmds.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/sql_cmds.c,v
-retrieving revision 1.43
-diff -u -r1.43 sql_cmds.c
---- src/dird/sql_cmds.c 1 Sep 2004 19:44:28 -0000 1.43
-+++ src/dird/sql_cmds.c 10 Nov 2004 20:38:46 -0000
-@@ -340,4 +340,16 @@
- "AND Path.PathId=File.PathId "
- "AND Filename.FilenameId=File.FilenameId "
- "ORDER BY Job.StartTime DESC LIMIT 1";
--
-+
-+const char *uar_jobids_fileindex =
-+ "SELECT Job.JobId, File.FileIndex FROM Job,File,Path,Filename,Client "
-+ "WHERE Job.JobId IN (%s) "
-+ "AND Job.JobId=File.JobId "
-+ "AND Job.StartTime<'%s' "
-+ "AND Path.Path='%s' "
-+ "AND Filename.Name='%s' "
-+ "AND Client.Name='%s' "
-+ "AND Job.ClientId=Client.ClientId "
-+ "AND Path.PathId=File.PathId "
-+ "AND Filename.FilenameId=File.FilenameId "
-+ "ORDER BY Job.StartTime DESC LIMIT 1";
-Index: src/dird/ua_restore.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-retrieving revision 1.84
-diff -u -r1.84 ua_restore.c
---- src/dird/ua_restore.c 15 Oct 2004 17:09:04 -0000 1.84
-+++ src/dird/ua_restore.c 10 Nov 2004 20:38:46 -0000
-@@ -48,7 +48,7 @@
- extern char *uar_inc, *uar_list_temp, *uar_sel_jobid_temp;
- extern char *uar_sel_all_temp1, *uar_sel_fileset, *uar_mediatype;
- extern char *uar_jobid_fileindex, *uar_dif, *uar_sel_all_temp;
--extern char *uar_count_files;
-+extern char *uar_count_files, *uar_jobids_fileindex;
-
-
- struct NAME_LIST {
-@@ -632,7 +632,12 @@
- {
- strip_trailing_junk(file);
- split_path_and_filename(rx, file);
-- Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname, rx->ClientName);
-+ if (*rx->JobIds == 0) {
-+ Mmsg(rx->query, uar_jobid_fileindex, date, rx->path, rx->fname, rx->ClientName);
-+ } else {
-+ Mmsg(rx->query, uar_jobids_fileindex, rx->JobIds, date,
-+ rx->path, rx->fname, rx->ClientName);
-+ }
- rx->found = false;
- /* Find and insert jobid and File Index */
- if (!db_sql_query(ua->db, rx->query, jobid_fileindex_handler, (void *)rx)) {
+++ /dev/null
-
- This patch corrects a Bacula crash after a "list nextvol" followed
- by "list media".
- It can be applied to 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-list.patch
- make
- make install
-
-
-Index: src/dird/ua_output.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_output.c,v
-retrieving revision 1.47
-diff -u -r1.47 ua_output.c
---- src/dird/ua_output.c 19 Sep 2004 18:56:24 -0000 1.47
-+++ src/dird/ua_output.c 13 Nov 2004 10:26:08 -0000
-@@ -42,11 +42,11 @@
- extern FILE *con_fd;
- extern brwlock_t con_lock;
-
--
- /* Imported functions */
-
- /* Forward referenced functions */
- static int do_list_cmd(UAContext *ua, const char *cmd, e_list_type llist);
-+static bool list_nextvol(UAContext *ua);
-
- /*
- * Turn auto display of console messages on/off
-@@ -401,58 +401,7 @@
- /* List next volume */
- } else if (strcasecmp(ua->argk[i], _("nextvol")) == 0 ||
- strcasecmp(ua->argk[i], _("nextvolume")) == 0) {
-- JOB *job;
-- JCR *jcr = ua->jcr;
-- POOL *pool;
-- RUN *run;
-- time_t runtime;
-- bool found = false;
--
-- i = find_arg_with_value(ua, "job");
-- if (i <= 0) {
-- if ((job = select_job_resource(ua)) == NULL) {
-- return 1;
-- }
-- } else {
-- job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
-- if (!job) {
-- Jmsg(jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
-- if ((job = select_job_resource(ua)) == NULL) {
-- return 1;
-- }
-- }
-- }
-- for (run=NULL; (run = find_next_run(run, job, runtime)); ) {
-- pool = run ? run->pool : NULL;
-- if (!complete_jcr_for_job(jcr, job, pool)) {
-- return 1;
-- }
--
-- if (!find_next_volume_for_append(jcr, &mr, 0)) {
-- bsendmsg(ua, _("Could not find next Volume.\n"));
-- if (jcr->db) {
-- db_close_database(jcr, jcr->db);
-- jcr->db = NULL;
-- }
-- return 1;
-- } else {
-- bsendmsg(ua, _("The next Volume to be used by Job \"%s\" will be %s\n"),
-- job->hdr.name, mr.VolumeName);
-- found = true;
-- }
-- if (jcr->db) {
-- db_close_database(jcr, jcr->db);
-- jcr->db = NULL;
-- }
-- }
-- if (jcr->db) {
-- db_close_database(jcr, jcr->db);
-- jcr->db = NULL;
-- }
-- if (!found) {
-- bsendmsg(ua, _("Could not find next Volume.\n"));
-- }
-- return 1;
-+ list_nextvol(ua);
- } else {
- bsendmsg(ua, _("Unknown list keyword: %s\n"), NPRT(ua->argk[i]));
- }
-@@ -460,6 +409,57 @@
- return 1;
- }
-
-+static bool list_nextvol(UAContext *ua)
-+{
-+ JOB *job;
-+ JCR *jcr = ua->jcr;
-+ POOL *pool;
-+ RUN *run;
-+ time_t runtime;
-+ bool found = false;
-+ MEDIA_DBR mr;
-+
-+ memset(&mr, 0, sizeof(mr));
-+ int i = find_arg_with_value(ua, "job");
-+ if (i <= 0) {
-+ if ((job = select_job_resource(ua)) == NULL) {
-+ return false;
-+ }
-+ } else {
-+ job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
-+ if (!job) {
-+ Jmsg(jcr, M_ERROR, 0, _("%s is not a job name.\n"), ua->argv[i]);
-+ if ((job = select_job_resource(ua)) == NULL) {
-+ return false;
-+ }
-+ }
-+ }
-+ for (run=NULL; (run = find_next_run(run, job, runtime)); ) {
-+ pool = run ? run->pool : NULL;
-+ if (!complete_jcr_for_job(jcr, job, pool)) {
-+ return false;
-+ }
-+
-+ if (!find_next_volume_for_append(jcr, &mr, 0)) {
-+ bsendmsg(ua, _("Could not find next Volume.\n"));
-+ } else {
-+ bsendmsg(ua, _("The next Volume to be used by Job \"%s\" will be %s\n"),
-+ job->hdr.name, mr.VolumeName);
-+ found = true;
-+ }
-+ if (jcr->db && jcr->db != ua->db) {
-+ db_close_database(jcr, jcr->db);
-+ jcr->db = NULL;
-+ }
-+ }
-+ if (!found) {
-+ bsendmsg(ua, _("Could not find next Volume.\n"));
-+ return false;
-+ }
-+ return true;
-+}
-+
-+
- /*
- * For a given job, we examine all his run records
- * to see if it is scheduled today or tomorrow.
+++ /dev/null
-
- This patch will keep the SD from blocking simultaneous Jobs during
- a tape mount.
-
- Apply it to 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-sd-block.patch
- make
- ...
-
-Index: src/stored/acquire.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/acquire.c,v
-retrieving revision 1.74
-diff -u -r1.74 acquire.c
---- src/stored/acquire.c 16 Oct 2004 11:51:32 -0000 1.74
-+++ src/stored/acquire.c 25 Oct 2004 16:12:46 -0000
-@@ -339,7 +339,10 @@
-
- if (do_mount || recycle) {
- Dmsg0(190, "Do mount_next_write_vol\n");
-- if (!mount_next_write_volume(dcr, release)) {
-+ V(mutex); /* don't lock everything during mount */
-+ bool mounted = mount_next_write_volume(dcr, release);
-+ P(mutex); /* re-lock */
-+ if (!mounted) {
- if (!job_canceled(jcr)) {
- /* Reduce "noise" -- don't print if job canceled */
- Jmsg(jcr, M_FATAL, 0, _("Could not ready device \"%s\" for append.\n"),
+++ /dev/null
-
- This patch fixes (hopefully) a segment fault in restore when an
- empty path is found for a file.
- Apply it to 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-tree.patch
- make
- make install
-
-Index: src/lib/tree.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/lib/tree.c,v
-retrieving revision 1.18
-diff -u -r1.18 tree.c
---- src/lib/tree.c 16 Jul 2004 07:23:40 -0000 1.18
-+++ src/lib/tree.c 21 Nov 2004 16:03:53 -0000
-@@ -87,6 +87,7 @@
- }
- Dmsg2(400, "count=%d size=%d\n", count, size);
- malloc_buf(root, size);
-+ root->cached_path_len = -1;
- root->cached_path = get_pool_memory(PM_FNAME);
- root->type = TN_ROOT;
- root->fname = "";
+++ /dev/null
-
- This patch fixes the calculation for the total number of files
- to be restored or verified by not double counting files that are
- split across a tape file or across tapes.
-
- To apply this patch, you must first have applied 1.36.0-verify.patch.
-
- Apply it with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-verify-2.patch
- make
- make install
- ...
-
-Index: src/dird/bsr.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/bsr.c,v
-retrieving revision 1.16
-diff -u -r1.16 bsr.c
---- src/dird/bsr.c 29 Oct 2004 22:11:43 -0000 1.16
-+++ src/dird/bsr.c 4 Nov 2004 10:37:37 -0000
-@@ -238,6 +238,8 @@
- {
- uint32_t count = 0;
- uint32_t total_count = 0;
-+ uint32_t LastIndex = 0;
-+ bool first = true;
- if (bsr) {
- /*
- * For a given volume, loop over all the JobMedia records.
-@@ -273,6 +275,15 @@
- fprintf(fd, "Count=%u\n", count);
- }
- total_count += count;
-+ /* If the same file is present on two tapes or in two files
-+ * on a tape, it is a continuation, and should not be treated
-+ * twice in the totals.
-+ */
-+ if (!first && LastIndex == bsr->VolParams[i].FirstIndex) {
-+ total_count--;
-+ }
-+ first = false;
-+ LastIndex = bsr->VolParams[i].LastIndex;
- }
- write_bsr(ua, bsr->next, fd);
- }
+++ /dev/null
-
- This patch fixes, at least partially, a Verify error where
- the count of files expected did not agree with the count
- found. There are still some cases where the expected count
- exceeds the found probably due to the same directory being
- examined multiple times.
-
- Apply the patch to 1.36.0 with:
-
- cd <bacula-source>
- patch -p0 <1.36.0-verify.patch
- make
- make install
-
-
-Index: src/dird/bsr.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/bsr.c,v
-retrieving revision 1.15
-diff -u -r1.15 bsr.c
---- src/dird/bsr.c 24 Sep 2004 15:53:00 -0000 1.15
-+++ src/dird/bsr.c 29 Oct 2004 22:05:24 -0000
-@@ -34,7 +34,7 @@
- #include "dird.h"
-
- /* Forward referenced functions */
--static int write_bsr(UAContext *ua, RBSR *bsr, FILE *fd);
-+static uint32_t write_bsr(UAContext *ua, RBSR *bsr, FILE *fd);
- void print_bsr(UAContext *ua, RBSR *bsr);
-
-
-@@ -178,11 +178,11 @@
- /*
- * Write the bootstrap records to file
- */
--int write_bsr_file(UAContext *ua, RBSR *bsr)
-+uint32_t write_bsr_file(UAContext *ua, RBSR *bsr)
- {
- FILE *fd;
- POOLMEM *fname = get_pool_memory(PM_MESSAGE);
-- int count = 0;;
-+ uint32_t count = 0;;
- bool err;
-
- Mmsg(fname, "%s/restore.bsr", working_directory);
-@@ -234,9 +234,10 @@
- return count;
- }
-
--static int write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
-+static uint32_t write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
- {
- uint32_t count = 0;
-+ uint32_t total_count = 0;
- if (bsr) {
- /*
- * For a given volume, loop over all the JobMedia records.
-@@ -271,10 +272,11 @@
- if (count) {
- fprintf(fd, "Count=%u\n", count);
- }
-+ total_count += count;
- }
- write_bsr(ua, bsr->next, fd);
- }
-- return count;
-+ return total_count;
- }
-
- void print_bsr(UAContext *ua, RBSR *bsr)
-Index: src/dird/protos.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/protos.h,v
-retrieving revision 1.54
-diff -u -r1.54 protos.h
---- src/dird/protos.h 24 Sep 2004 12:30:14 -0000 1.54
-+++ src/dird/protos.h 29 Oct 2004 22:05:24 -0000
-@@ -44,7 +44,7 @@
- RBSR *new_bsr();
- void free_bsr(RBSR *bsr);
- int complete_bsr(UAContext *ua, RBSR *bsr);
--int write_bsr_file(UAContext *ua, RBSR *bsr);
-+uint32_t write_bsr_file(UAContext *ua, RBSR *bsr);
- void add_findex(RBSR *bsr, uint32_t JobId, int32_t findex);
- RBSR_FINDEX *new_findex();
-
-@@ -62,7 +62,7 @@
-
- /* fd_cmds.c */
- extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
-- int max_retry_time, int verbose);
-+ int max_retry_time, int verbose);
- extern int send_include_list(JCR *jcr);
- extern int send_exclude_list(JCR *jcr);
- extern int send_bootstrap_file(JCR *jcr);
-@@ -70,7 +70,7 @@
- extern int get_attributes_and_put_in_catalog(JCR *jcr);
- extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
- extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
-- char *link, char *attr, int stream);
-+ char *link, char *attr, int stream);
- extern void get_level_since_time(JCR *jcr, char *since, int since_len);
- extern int send_run_before_and_after_commands(JCR *jcr);
-
-@@ -97,7 +97,7 @@
-
- /* msgchan.c */
- extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
-- int max_retry_time, int verbose);
-+ int max_retry_time, int verbose);
- extern int start_storage_daemon_job(JCR *jcr);
- extern int start_storage_daemon_message_thread(JCR *jcr);
- extern int bget_dirmsg(BSOCK *bs);
-@@ -149,28 +149,28 @@
- void free_ua_context(UAContext *ua);
-
- /* ua_select.c */
--STORE *select_storage_resource(UAContext *ua);
--JOB *select_job_resource(UAContext *ua);
--JOB *select_restore_job_resource(UAContext *ua);
--CLIENT *select_client_resource(UAContext *ua);
-+STORE *select_storage_resource(UAContext *ua);
-+JOB *select_job_resource(UAContext *ua);
-+JOB *select_restore_job_resource(UAContext *ua);
-+CLIENT *select_client_resource(UAContext *ua);
- FILESET *select_fileset_resource(UAContext *ua);
--int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
--int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
--bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
--int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
--
--void start_prompt(UAContext *ua, const char *msg);
--void add_prompt(UAContext *ua, const char *prompt);
--int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
--CAT *get_catalog_resource(UAContext *ua);
-+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-+int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-+bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-+int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-+
-+void start_prompt(UAContext *ua, const char *msg);
-+void add_prompt(UAContext *ua, const char *prompt);
-+int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
-+CAT *get_catalog_resource(UAContext *ua);
- STORE *get_storage_resource(UAContext *ua, int use_default);
--int get_media_type(UAContext *ua, char *MediaType, int max_media);
--bool get_pool_dbr(UAContext *ua, POOL_DBR *pr);
--int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-+int get_media_type(UAContext *ua, char *MediaType, int max_media);
-+bool get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-+int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
- POOL *get_pool_resource(UAContext *ua);
- POOL *select_pool_resource(UAContext *ua);
- CLIENT *get_client_resource(UAContext *ua);
--int get_job_dbr(UAContext *ua, JOB_DBR *jr);
-+int get_job_dbr(UAContext *ua, JOB_DBR *jr);
-
- int find_arg_keyword(UAContext *ua, const char **list);
- int find_arg(UAContext *ua, const char *keyword);
+++ /dev/null
-
-25Oct04 1.36.0-sd-block.patch
- This patch will keep the SD from blocking simultaneous Jobs during
- a tape mount.
-
-30Oct04 1.36.0-verify.patch
- This patch fixes, at least partially, a Verify error where
- the count of files expected did not agree with the count
- found. There are still some cases where the expected count
- exceeds the found probably due to the same directory being
- examined multiple times.
-
-04Nov04 1.36.0-verify-2.patch
- This patch fixes the calculation for the total number of files
- to be restored or verified by not double counting files that are
- split across a tape file or across tapes.
- To apply this patch, you must first have applied 1.36.0-verify.patch.
-
-10Nov04 1.36.0-jobid-restore.patch
- This patch fixes a restore to permit specifying both a JobId and
- a filename or list of files to be restored. Apply to 1.36.0 with:
-
-11Nov04 1.36.0-jobdefs.patch
- This patch fixes JobDefs so that if a Storage resource is
- specified in a Job, it is not overridden by the JobDefs.
-
-13Nov04 1.36.0-list.patch
- This patch corrects a Bacula crash after a "list nextvol" followed
- by "list media".
-
-21Nov04 1.36.0-tree.patch
- This patch fixes (hopefully) a segment fault in restore when an
- empty path is found for a file.
-
-21Nov04 1.36.0-autochanger.patch
- This patch should fix a problem where the autochanger thinks
- a Volume is in the current magazine and loops a few times then
- gives up.
-
-24Nov04 1.36.0-autochanger2.patch
- This patch fixes an autochanger problem where Bacula was trying
- to access a Volume that was not in the autochanger. You *must*
- also apply patch 1.36.0-autochanger.patch for this patch to work
- correctly. This patch will probably also correct some problems
- introduced with version 1.36 (dcrs) that make update slots
- fail.
-
+++ /dev/null
-
- This patch fixes some typos with ACL checking that results
- in the incorrect name being used for the check.
- This could lead to security problems with unwanted
- access by restricted consoles.
- Apply the patch to 1.36.1 with:
-
- cd <bacula-source>
- patch -p0 <1.36.1-acl.patch
- make
- ...
-
-
-
-Index: src/dird/ua_run.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-retrieving revision 1.58
-diff -u -r1.58 ua_run.c
---- src/dird/ua_run.c 8 Nov 2004 21:12:12 -0000 1.58
-+++ src/dird/ua_run.c 30 Jan 2005 16:41:09 -0000
-@@ -325,12 +330,13 @@
- pool = job->pool; /* use default */
- }
- if (!pool) {
-- return 1;
-- } else if (!acl_access_ok(ua, Pool_ACL, store->hdr.name)) {
-+ return 0;
-+ } else if (!acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
- bsendmsg(ua, _("No authorization. Pool \"%s\".\n"),
- pool->hdr.name);
-- return 1;
-+ return 0;
- }
-+ Dmsg1(200, "Using pool\n", pool->hdr.name);
-
- if (client_name) {
- client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
-@@ -344,12 +350,13 @@
- client = job->client; /* use default */
- }
- if (!client) {
-- return 1;
-- } else if (!acl_access_ok(ua, Client_ACL, store->hdr.name)) {
-+ return 0;
-+ } else if (!acl_access_ok(ua, Client_ACL, client->hdr.name)) {
- bsendmsg(ua, _("No authorization. Client \"%s\".\n"),
- client->hdr.name);
-- return 1;
-+ return 0;
- }
-+ Dmsg1(200, "Using client=%s\n", client->hdr.name);
-
- if (fileset_name) {
- fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
-@@ -361,11 +368,11 @@
- fileset = job->fileset; /* use default */
- }
- if (!fileset) {
-- return 1;
-- } else if (!acl_access_ok(ua, FileSet_ACL, store->hdr.name)) {
-+ return 0;
-+ } else if (!acl_access_ok(ua, FileSet_ACL, fileset->hdr.name)) {
- bsendmsg(ua, _("No authorization. FileSet \"%s\".\n"),
- fileset->hdr.name);
-- return 1;
-+ return 0;
- }
-
- if (verify_job_name) {
+++ /dev/null
-
- This patch should correct a seg fault in the FD that occurs
- at the end of a job when the job uses old style include/excludes.
- Apply the patch to version 1.36.1 with:
-
- cd <bacula-source>
- patch -p0 <1.36.1-fileset.patch
- make
- make install
- ...
-
-Index: src/findlib/match.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/findlib/match.c,v
-retrieving revision 1.21
-diff -u -r1.21 match.c
---- src/findlib/match.c 21 Dec 2004 16:18:37 -0000 1.21
-+++ src/findlib/match.c 24 Dec 2004 10:17:29 -0000
-@@ -10,7 +10,7 @@
- *
- */
- /*
-- Copyright (C) 2001-2004 Kern Sibbald and John Walker
-+ Copyright (C) 2001-2004 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
-@@ -74,19 +74,21 @@
- free(inc);
- inc = next_inc;
- }
-+ ff->included_files_list = NULL;
-
- for (exc=ff->excluded_files_list; exc; ) {
- next_exc = exc->next;
- free(exc);
- exc = next_exc;
- }
-+ ff->excluded_files_list = NULL;
-
- for (exc=ff->excluded_paths_list; exc; ) {
- next_exc = exc->next;
- free(exc);
- exc = next_exc;
- }
--
-+ ff->excluded_paths_list = NULL;
- }
-
- /*
-@@ -111,42 +113,42 @@
- if (prefixed) {
- for (rp=fname; *rp && *rp != ' '; rp++) {
- switch (*rp) {
-- case 'a': /* alway replace */
-- case '0': /* no option */
-+ case 'a': /* alway replace */
-+ case '0': /* no option */
- break;
-- case 'f':
-+ case 'f':
- inc->options |= FO_MULTIFS;
- break;
-- case 'h': /* no recursion */
-+ case 'h': /* no recursion */
- inc->options |= FO_NO_RECURSION;
- break;
-- case 'M': /* MD5 */
-+ case 'M': /* MD5 */
- inc->options |= FO_MD5;
- break;
-- case 'n':
-+ case 'n':
- inc->options |= FO_NOREPLACE;
- break;
-- case 'p': /* use portable data format */
-+ case 'p': /* use portable data format */
- inc->options |= FO_PORTABLE;
- break;
-- case 'r': /* read fifo */
-+ case 'r': /* read fifo */
- inc->options |= FO_READFIFO;
- break;
-- case 'S':
-+ case 'S':
- inc->options |= FO_SHA1;
- break;
-- case 's':
-+ case 's':
- inc->options |= FO_SPARSE;
- break;
-- case 'm':
-+ case 'm':
- inc->options |= FO_MTIMEONLY;
- break;
-- case 'k':
-+ case 'k':
- inc->options |= FO_KEEPATIME;
- break;
-- case 'V': /* verify options */
-+ case 'V': /* verify options */
- /* Copy Verify Options */
-- for (j=0; *rp && *rp != ':'; rp++) {
-+ for (j=0; *rp && *rp != ':'; rp++) {
- inc->VerifyOpts[j] = *rp;
- if (j < (int)sizeof(inc->VerifyOpts) - 1) {
- j++;
-@@ -154,19 +156,19 @@
- }
- inc->VerifyOpts[j] = 0;
- break;
-- case 'w':
-+ case 'w':
- inc->options |= FO_IF_NEWER;
- break;
-- case 'A':
-+ case 'A':
- inc->options |= FO_ACL;
- break;
-- case 'Z': /* gzip compression */
-+ case 'Z': /* gzip compression */
- inc->options |= FO_GZIP;
-- inc->level = *++rp - '0';
-- Dmsg1(200, "Compression level=%d\n", inc->level);
-+ inc->level = *++rp - '0';
-+ Dmsg1(200, "Compression level=%d\n", inc->level);
- break;
- default:
-- Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *rp);
-+ Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *rp);
- break;
- }
- }
-@@ -199,7 +201,7 @@
- /* Convert any \'s into /'s */
- for (p=inc->fname; *p; p++) {
- if (*p == '\\') {
-- *p = '/';
-+ *p = '/';
- }
- }
- #endif
-@@ -249,7 +251,7 @@
- /* Convert any \'s into /'s */
- for (char *p=exc->fname; *p; p++) {
- if (*p == '\\') {
-- *p = '/';
-+ *p = '/';
- }
- }
- #endif
-@@ -329,7 +331,7 @@
- }
- for ( ; exc; exc=exc->next ) {
- if (fnmatch(exc->fname, file, fnmode|FNM_PATHNAME) == 0) {
-- Dmsg2(900, "Match exc pat=%s: file=%s:\n", exc->fname, file);
-+ Dmsg2(900, "Match exc pat=%s: file=%s:\n", exc->fname, file);
- return 1;
- }
- Dmsg2(900, "No match exc pat=%s: file=%s:\n", exc->fname, file);
+++ /dev/null
-
- This patch should hold jobs in the Director's start queue if
- more than one simultaneous backup job wants to use the same
- Storage device with two different Pools (i.e. 2 Volumes).
- Apply the patch to version 1.36.1 with:
-
- cd <bacula-source>
- patch -p0 <1.36.1-pool.patch
- make
- make install
- ...
-
-Index: src/dird/jobq.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/jobq.c,v
-retrieving revision 1.25
-retrieving revision 1.26
-diff -u -r1.25 -r1.26
---- src/dird/jobq.c 24 Sep 2004 12:30:14 -0000 1.25
-+++ src/dird/jobq.c 3 Dec 2004 21:00:18 -0000 1.26
-@@ -10,7 +10,7 @@
- *
- * Kern Sibbald, July MMIII
- *
-- * Version $Id$
-+ * Version $Id$
- *
- * This code was adapted from the Bacula workq, which was
- * adapted from "Programming with POSIX Threads", by
-@@ -40,6 +40,7 @@
- #include "bacula.h"
- #include "dird.h"
-
-+extern JCR *jobs;
-
- /* Forward referenced functions */
- extern "C" void *jobq_server(void *arg);
-@@ -47,6 +48,8 @@
-
- static int start_server(jobq_t *jq);
-
-+
-+
- /*
- * Initialize a job queue
- *
-@@ -544,6 +547,7 @@
- for ( ; je; ) {
- /* je is current job item on the queue, jn is the next one */
- JCR *jcr = je->jcr;
-+ bool skip_this_jcr = false;
- jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
- Dmsg3(300, "Examining Job=%d JobPri=%d want Pri=%d\n",
- jcr->JobId, jcr->JobPriority, Priority);
-@@ -560,14 +564,40 @@
- jcr->store->MaxConcurrentJobs = 1;
- } else {
- set_jcr_job_status(jcr, JS_WaitStoreRes);
-- je = jn;
-+ je = jn; /* point to next waiting job */
- continue;
- }
-+ /* We are not doing a Restore or Verify */
-+ } else if (jcr->store->NumConcurrentJobs == 0 &&
-+ jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
-+ /* Simple case, first job */
-+ jcr->store->NumConcurrentJobs = 1;
- } else if (jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
-- jcr->store->NumConcurrentJobs++;
-- } else {
-+ /*
-+ * At this point, we already have at least one Job running
-+ * for this Storage daemon, so we must ensure that there
-+ * is no Volume conflict. In general, it should be OK, if
-+ * all Jobs pull from the same Pool, so we check the Pools.
-+ */
-+ JCR *njcr;
-+ lock_jcr_chain();
-+ for (njcr=jobs; njcr; njcr=njcr->next) {
-+ if (njcr->JobId == 0 || njcr == jcr) {
-+ continue;
-+ }
-+ if (njcr->pool != jcr->pool) {
-+ skip_this_jcr = true;
-+ break;
-+ }
-+ }
-+ unlock_jcr_chain();
-+ if (!skip_this_jcr) {
-+ jcr->store->NumConcurrentJobs++;
-+ }
-+ }
-+ if (skip_this_jcr) {
- set_jcr_job_status(jcr, JS_WaitStoreRes);
-- je = jn;
-+ je = jn; /* point to next waiting job */
- continue;
- }
-
-@@ -580,7 +610,7 @@
- jcr->store->MaxConcurrentJobs = jcr->saveMaxConcurrentJobs;
- }
- set_jcr_job_status(jcr, JS_WaitClientRes);
-- je = jn;
-+ je = jn; /* point to next waiting job */
- continue;
- }
- if (jcr->job->NumConcurrentJobs < jcr->job->MaxConcurrentJobs) {
-@@ -593,7 +623,7 @@
- }
- jcr->client->NumConcurrentJobs--;
- set_jcr_job_status(jcr, JS_WaitJobRes);
-- je = jn;
-+ je = jn; /* Point to next waiting job */
- continue;
- }
- /* Got all locks, now remove it from wait queue and append it
-@@ -603,7 +633,7 @@
- jq->waiting_jobs->remove(je);
- jq->ready_jobs->append(je);
- Dmsg1(300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
-- je = jn;
-+ je = jn; /* Point to next waiting job */
- } /* end for loop */
- break;
- } /* end while loop */
-Index: src/lib/jcr.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/lib/jcr.c,v
-retrieving revision 1.61
-retrieving revision 1.62
-diff -u -r1.61 -r1.62
---- src/lib/jcr.c 15 Nov 2004 22:43:33 -0000 1.61
-+++ src/lib/jcr.c 3 Dec 2004 21:00:19 -0000 1.62
-@@ -3,7 +3,7 @@
- *
- * Kern E. Sibbald, December 2000
- *
-- * Version $Id$
-+ * Version $Id$
- *
- * These routines are thread safe.
- *
-@@ -43,7 +43,7 @@
- dlist *last_jobs = NULL;
- const int max_last_jobs = 10;
-
--static JCR *jobs = NULL; /* pointer to JCR chain */
-+JCR *jobs = NULL; /* pointer to JCR chain */
- static brwlock_t lock; /* lock for last jobs and JCR chain */
-
- void init_last_jobs_list()
+++ /dev/null
- This patch fixes Bacula so that it does not exit if there
- is a syntax error in its conf file during a reload command.
- Apply the patch to 1.36.1 with:
-
- cd <bacula-source>
- patch -p0 <1.36.1-reload.patch
- make
- make install
-
---- ../branch-1.36.1/src/dird/dird.c 2004-11-11 18:30:32.000000000 +0100
-+++ src/dird/dird.c 2004-12-21 18:15:10.625754501 +0100
-@@ -372,6 +375,7 @@
- JCR *jcr;
- int njobs = 0; /* number of running jobs */
- int table, rtable;
-+ bool ok;
-
- if (already_here) {
- abort(); /* Oops, recursion -> die */
-@@ -396,16 +400,17 @@
- reload_table[table].res_table = save_config_resources();
- Dmsg1(100, "Saved old config in table %d\n", table);
-
-- parse_config(configfile);
-+ ok = parse_config(configfile, 0); /* no exit on error */
-
- Dmsg0(100, "Reloaded config file\n");
-- if (!check_resources()) {
-+ if (!ok || !check_resources()) {
- rtable = find_free_reload_table_entry(); /* save new, bad table */
- if (rtable < 0) {
- Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
- Jmsg(NULL, M_ERROR_TERM, 0, _("Out of reload table entries. Giving up.\n"));
- } else {
- Jmsg(NULL, M_ERROR, 0, _("Please correct configuration file: %s\n"), configfile);
-+ Jmsg(NULL, M_ERROR, 0, _("Resetting previous configuration.\n"));
- }
- reload_table[rtable].res_table = save_config_resources();
- /* Now restore old resoure values */
-@@ -465,8 +470,8 @@
- job = (JOB *)GetNextRes(R_JOB, NULL);
- director = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
- if (!director) {
-- Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n\
--Without that I don't know who I am :-(\n"), configfile);
-+ Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in %s\n"
-+"Without that I don't know who I am :-(\n"), configfile);
- OK = false;
- } else {
- set_working_directory(director->working_directory);
+++ /dev/null
-
- This patch should fix "update slots" with two different magazines
- in different pools by checking the pool when zapping the InChanger.
- Apply to 1.36.1 with:
-
- cd <bacula-source>
- patch -p0 <1.36.1-slots.patch
- make
- make install
-
-
-Index: src/cats/sql_update.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/cats/sql_update.c,v
-retrieving revision 1.52
-diff -u -r1.52 sql_update.c
---- src/cats/sql_update.c 17 Nov 2004 22:48:21 -0000 1.52
-+++ src/cats/sql_update.c 3 Dec 2004 21:11:09 -0000
-@@ -389,7 +389,8 @@
- {
- if (mr->InChanger != 0 && mr->Slot != 0) {
- Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0 WHERE "
-- "Slot=%d AND MediaId!=%u", mr->Slot, mr->MediaId);
-+ "Slot=%d AND PoolId=%u AND MediaId!=%u",
-+ mr->Slot, mr->PoolId, mr->MediaId);
- Dmsg1(400, "%s\n", mdb->cmd);
- UPDATE_DB(jcr, mdb, mdb->cmd);
- }
+++ /dev/null
-
- This patch fixes the despooling size printed in the Job
- report. Previously, it reported the total size for the
- device. This patch makes it report the size for the job.
- Apply the patch to 1.36.1 with:
-
- cd <bacula-source>
- patch -p0 <1.36.1-spool.patch
- make
- make install
- ...
-
-Index: src/stored/spool.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/spool.c,v
-retrieving revision 1.22
-diff -u -r1.22 spool.c
---- src/stored/spool.c 16 Oct 2004 11:51:32 -0000 1.22
-+++ src/stored/spool.c 18 Dec 2004 20:39:02 -0000
-@@ -201,7 +201,7 @@
- Dmsg0(100, "Despooling data\n");
- Jmsg(jcr, M_INFO, 0, _("%s spooled data to Volume. Despooling %s bytes ...\n"),
- commit?"Committing":"Writing",
-- edit_uint64_with_commas(jcr->dcr->dev->spool_size, ec1));
-+ edit_uint64_with_commas(jcr->dcr->spool_size, ec1));
- dcr->spooling = false;
- lock_device(dcr->dev);
- dcr->dev_locked = true;
+++ /dev/null
- This patch fixes a problem with overriding storage daemon
- specifications. Previously they were not always honored.
- This implements more uniform handling. It also eliminates
- an orphaned buffer situation using JobDefs.
- Apply to version 1.36.1 with:
-
- cd <bacula-source>
- patch -p0 <1.36.1-store.patch
- make
- make install
- ...
-
-Index: src/dird/job.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/job.c,v
-retrieving revision 1.92
-diff -u -r1.92 job.c
---- src/dird/job.c 21 Nov 2004 13:10:15 -0000 1.92
-+++ src/dird/job.c 21 Dec 2004 13:04:08 -0000
-@@ -4,10 +4,10 @@
- *
- * Kern Sibbald, October MM
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
-- Copyright (C) 2000-2004 Kern Sibbald and John Walker
-+ Copyright (C) 2000-2004 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
-@@ -344,7 +344,7 @@
- if (!ua->jcr->storage[0]) {
- copy_storage(ua->jcr, jcr);
- } else {
-- ua->jcr->store = jcr->store;
-+ set_storage(ua->jcr, jcr->store);
- }
- if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
- bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
-@@ -724,6 +724,12 @@
- if (jcr->term_wait_inited) {
- pthread_cond_destroy(&jcr->term_wait);
- }
-+ /* Delete lists setup to hold storage pointers */
-+ for (int i=0; i<MAX_STORE; i++) {
-+ if (jcr->storage[i]) {
-+ delete jcr->storage[i];
-+ }
-+ }
- jcr->job_end_push.destroy();
- Dmsg0(200, "End dird free_jcr\n");
- }
-@@ -749,10 +755,17 @@
- break;
- }
- jcr->JobPriority = job->Priority;
-+ /* Copy storage definitions -- deleted in dir_free_jcr above */
- for (int i=0; i<MAX_STORE; i++) {
-- jcr->storage[i] = job->storage[i];
-+ STORE *st;
-+ if (job->storage[i]) {
-+ jcr->storage[i] = New(alist(10, not_owned_by_alist));
-+ foreach_alist(st, job->storage[i]) {
-+ jcr->storage[i]->append(st);
-+ }
-+ }
- }
-- if (!jcr->store && jcr->storage[0]) {
-+ if (jcr->storage[0]) {
- jcr->store = (STORE *)jcr->storage[0]->first();
- }
- jcr->client = job->client;
-@@ -805,6 +818,9 @@
- for (int i=0; i < MAX_STORE; i++) {
- if (old_jcr->storage[i]) {
- STORE *st;
-+ if (old_jcr->storage[i]) {
-+ delete old_jcr->storage[i];
-+ }
- new_jcr->storage[i] = New(alist(10, not_owned_by_alist));
- foreach_alist(st, old_jcr->storage[i]) {
- new_jcr->storage[i]->append(st);
-@@ -817,3 +833,10 @@
- }
- }
- }
-+
-+/* Set storage override */
-+void set_storage(JCR *jcr, STORE *store)
-+{
-+ jcr->store = store;
-+ jcr->storage[0]->prepend(store);
-+}
-Index: src/dird/msgchan.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/msgchan.c,v
-retrieving revision 1.32
-diff -u -r1.32 msgchan.c
---- src/dird/msgchan.c 29 Sep 2004 19:58:17 -0000 1.32
-+++ src/dird/msgchan.c 21 Dec 2004 13:04:08 -0000
-@@ -13,10 +13,10 @@
- * Create a thread to interact with the Storage daemon
- * who returns a job status and requests Catalog services, etc.
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
-- Copyright (C) 2000-2004 Kern Sibbald and John Walker
-+ Copyright (C) 2000-2004 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
-@@ -64,10 +64,9 @@
- int max_retry_time, int verbose)
- {
- BSOCK *sd;
-- STORE *store = jcr->store;
-- if (!store) {
-- jcr->store = store = (STORE *)jcr->storage[0]->first();
-- }
-+ STORE *store;
-+
-+ store = (STORE *)jcr->storage[0]->first();
-
- /*
- * Open message channel with the Storage daemon
-@@ -94,13 +93,13 @@
- */
- int start_storage_daemon_job(JCR *jcr)
- {
-- int status;
-+ int status = 0;
- STORE *storage;
- BSOCK *sd;
- char auth_key[100];
- POOL_MEM device_name, pool_name, pool_type, media_type;
-+ int i;
-
-- storage = jcr->store;
- sd = jcr->store_bsock;
- /*
- * Now send JobId and permissions, and get back the authorization key.
-@@ -139,23 +138,29 @@
- /*
- * Send use device = xxx media = yyy pool = zzz
- */
-- pm_strcpy(device_name, storage->dev_name);
-- pm_strcpy(media_type, storage->media_type);
-- pm_strcpy(pool_type, jcr->pool->pool_type);
-- pm_strcpy(pool_name, jcr->pool->hdr.name);
-- bash_spaces(device_name);
-- bash_spaces(media_type);
-- bash_spaces(pool_type);
-- bash_spaces(pool_name);
-- bnet_fsend(sd, use_device, device_name.c_str(),
-- media_type.c_str(), pool_name.c_str(), pool_type.c_str());
-- Dmsg1(110, ">stored: %s", sd->msg);
-- status = response(jcr, sd, OK_device, "Use Device", NO_DISPLAY);
-- if (!status) {
-- pm_strcpy(pool_type, sd->msg); /* save message */
-- Jmsg(jcr, M_FATAL, 0, _("\n"
-- " Storage daemon didn't accept Device \"%s\" because:\n %s"),
-- device_name.c_str(), pool_type.c_str()/* sd->msg */);
-+
-+ for (i=0; i < MAX_STORE; i++) {
-+ if (jcr->storage[i]) {
-+ storage = (STORE *)jcr->storage[i]->first();
-+ pm_strcpy(device_name, storage->dev_name);
-+ pm_strcpy(media_type, storage->media_type);
-+ pm_strcpy(pool_type, jcr->pool->pool_type);
-+ pm_strcpy(pool_name, jcr->pool->hdr.name);
-+ bash_spaces(device_name);
-+ bash_spaces(media_type);
-+ bash_spaces(pool_type);
-+ bash_spaces(pool_name);
-+ bnet_fsend(sd, use_device, device_name.c_str(),
-+ media_type.c_str(), pool_name.c_str(), pool_type.c_str());
-+ Dmsg1(110, ">stored: %s", sd->msg);
-+ status = response(jcr, sd, OK_device, "Use Device", NO_DISPLAY);
-+ if (!status) {
-+ pm_strcpy(pool_type, sd->msg); /* save message */
-+ Jmsg(jcr, M_FATAL, 0, _("\n"
-+ " Storage daemon didn't accept Device \"%s\" because:\n %s"),
-+ device_name.c_str(), pool_type.c_str()/* sd->msg */);
-+ }
-+ }
- }
- return status;
- }
-Index: src/dird/protos.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/protos.h,v
-retrieving revision 1.56
-diff -u -r1.56 protos.h
---- src/dird/protos.h 17 Nov 2004 22:48:22 -0000 1.56
-+++ src/dird/protos.h 21 Dec 2004 13:04:08 -0000
-@@ -1,7 +1,7 @@
- /*
- * Director external function prototypes
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
-@@ -62,7 +62,7 @@
-
- /* fd_cmds.c */
- extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
-- int max_retry_time, int verbose);
-+ int max_retry_time, int verbose);
- extern int send_include_list(JCR *jcr);
- extern int send_exclude_list(JCR *jcr);
- extern int send_bootstrap_file(JCR *jcr);
-@@ -70,7 +70,7 @@
- extern int get_attributes_and_put_in_catalog(JCR *jcr);
- extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
- extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
-- char *link, char *attr, int stream);
-+ char *link, char *attr, int stream);
- extern void get_level_since_time(JCR *jcr, char *since, int since_len);
- extern int send_run_before_and_after_commands(JCR *jcr);
-
-@@ -91,13 +91,14 @@
- extern int cancel_job(UAContext *ua, JCR *jcr);
- extern void init_jcr_job_record(JCR *jcr);
- extern void copy_storage(JCR *new_jcr, JCR *old_jcr);
-+extern void set_storage(JCR *jcr, STORE *store);
-
- /* mountreq.c */
- extern void mount_request(JCR *jcr, BSOCK *bs, char *buf);
-
- /* msgchan.c */
- extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
-- int max_retry_time, int verbose);
-+ int max_retry_time, int verbose);
- extern int start_storage_daemon_job(JCR *jcr);
- extern int start_storage_daemon_message_thread(JCR *jcr);
- extern int bget_dirmsg(BSOCK *bs);
-@@ -149,28 +150,28 @@
- void free_ua_context(UAContext *ua);
-
- /* ua_select.c */
--STORE *select_storage_resource(UAContext *ua);
--JOB *select_job_resource(UAContext *ua);
--JOB *select_restore_job_resource(UAContext *ua);
--CLIENT *select_client_resource(UAContext *ua);
-+STORE *select_storage_resource(UAContext *ua);
-+JOB *select_job_resource(UAContext *ua);
-+JOB *select_restore_job_resource(UAContext *ua);
-+CLIENT *select_client_resource(UAContext *ua);
- FILESET *select_fileset_resource(UAContext *ua);
--int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
--int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
--bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
--int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
--
--void start_prompt(UAContext *ua, const char *msg);
--void add_prompt(UAContext *ua, const char *prompt);
--int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
--CAT *get_catalog_resource(UAContext *ua);
-+int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-+int select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-+bool select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-+int select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-+
-+void start_prompt(UAContext *ua, const char *msg);
-+void add_prompt(UAContext *ua, const char *prompt);
-+int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt);
-+CAT *get_catalog_resource(UAContext *ua);
- STORE *get_storage_resource(UAContext *ua, int use_default);
--int get_media_type(UAContext *ua, char *MediaType, int max_media);
--bool get_pool_dbr(UAContext *ua, POOL_DBR *pr);
--int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-+int get_media_type(UAContext *ua, char *MediaType, int max_media);
-+bool get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-+int get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
- POOL *get_pool_resource(UAContext *ua);
- POOL *select_pool_resource(UAContext *ua);
- CLIENT *get_client_resource(UAContext *ua);
--int get_job_dbr(UAContext *ua, JOB_DBR *jr);
-+int get_job_dbr(UAContext *ua, JOB_DBR *jr);
-
- int find_arg_keyword(UAContext *ua, const char **list);
- int find_arg(UAContext *ua, const char *keyword);
-@@ -190,3 +191,6 @@
-
- /* ua_purge.c */
- int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr);
-+
-+/* ua_run.c */
-+extern int run_cmd(UAContext *ua, const char *cmd);
-Index: src/dird/scheduler.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/scheduler.c,v
-retrieving revision 1.27
-diff -u -r1.27 scheduler.c
---- src/dird/scheduler.c 3 Oct 2004 19:47:34 -0000 1.27
-+++ src/dird/scheduler.c 21 Dec 2004 13:04:08 -0000
-@@ -10,7 +10,7 @@
- * Version $Id$
- */
- /*
-- Copyright (C) 2000-2004 Kern Sibbald and John Walker
-+ Copyright (C) 2000-2004 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
-@@ -157,7 +157,7 @@
- jcr->dif_pool = run->dif_pool; /* override dif pool */
- }
- if (run->storage) {
-- jcr->store = run->storage; /* override storage */
-+ set_storage(jcr, run->storage); /* override storage */
- }
- if (run->msgs) {
- jcr->messages = run->msgs; /* override messages */
-Index: src/dird/ua.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua.h,v
-retrieving revision 1.23
-diff -u -r1.23 ua.h
---- src/dird/ua.h 18 Jun 2004 10:07:41 -0000 1.23
-+++ src/dird/ua.h 21 Dec 2004 13:04:08 -0000
-@@ -3,7 +3,7 @@
- *
- * Kern Sibbald, August MMI
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
-@@ -48,6 +48,7 @@
- bool automount; /* if set, mount after label */
- bool quit; /* if set, quit */
- bool verbose; /* set for normal UA verbosity */
-+ bool batch; /* set for non-interactive mode */
- uint32_t pint32_val; /* positive integer */
- int32_t int32_val; /* positive/negative */
- };
-Index: src/dird/ua_cmds.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_cmds.c,v
-retrieving revision 1.127
-diff -u -r1.127 ua_cmds.c
---- src/dird/ua_cmds.c 4 Oct 2004 20:34:01 -0000 1.127
-+++ src/dird/ua_cmds.c 21 Dec 2004 13:04:10 -0000
-@@ -4,7 +4,7 @@
- *
- * Kern Sibbald, September MM
- *
-- * Version $Id$
-+ * Version $Id$
- */
-
- /*
-@@ -52,7 +52,6 @@
- extern int gui_cmd(UAContext *ua, const char *cmd);
- extern int sqlquerycmd(UAContext *ua, const char *cmd);
- extern int querycmd(UAContext *ua, const char *cmd);
--extern int run_cmd(UAContext *ua, const char *cmd);
- extern int retentioncmd(UAContext *ua, const char *cmd);
- extern int prunecmd(UAContext *ua, const char *cmd);
- extern int purgecmd(UAContext *ua, const char *cmd);
-@@ -1195,7 +1194,7 @@
- BSOCK *sd;
- JCR *jcr = ua->jcr;
-
-- jcr->store = store;
-+ set_storage(jcr, store);
- /* Try connecting for up to 15 seconds */
- bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d\n"),
- store->hdr.name, store->address, store->SDport);
-@@ -1254,8 +1253,10 @@
- /* Count Storage items */
- LockRes();
- store = NULL;
-- for (i=0; (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)); i++)
-- { }
-+ i = 0;
-+ foreach_res(store, R_STORAGE) {
-+ i++;
-+ }
- unique_store = (STORE **) malloc(i * sizeof(STORE));
- /* Find Unique Storage address/port */
- store = (STORE *)GetNextRes(R_STORAGE, NULL);
-@@ -1286,8 +1287,10 @@
- /* Count Client items */
- LockRes();
- client = NULL;
-- for (i=0; (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)); i++)
-- { }
-+ i = 0;
-+ foreach_res(client, R_CLIENT) {
-+ i++;
-+ }
- unique_client = (CLIENT **) malloc(i * sizeof(CLIENT));
- /* Find Unique Client address/port */
- client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
-@@ -1841,7 +1844,7 @@
- Dmsg2(120, "Found storage, MediaType=%s DevName=%s\n",
- store->media_type, store->dev_name);
-
-- jcr->store = store;
-+ set_storage(jcr, store);
- if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
- bsendmsg(ua, _("Failed to connect to Storage daemon.\n"));
- return;
-Index: src/dird/ua_label.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_label.c,v
-retrieving revision 1.38
-diff -u -r1.38 ua_label.c
---- src/dird/ua_label.c 17 Aug 2004 14:40:09 -0000 1.38
-+++ src/dird/ua_label.c 21 Dec 2004 13:04:10 -0000
-@@ -8,7 +8,7 @@
- */
-
- /*
-- Copyright (C) 2000-2004 Kern Sibbald and John Walker
-+ Copyright (C) 2000-2004 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
-@@ -170,7 +170,7 @@
- if (!store) {
- return 1;
- }
-- ua->jcr->store = store;
-+ set_storage(ua->jcr, store);
-
- scan = find_arg(ua, _("scan")) >= 0;
-
-@@ -296,7 +296,7 @@
- if (!store) {
- return 1;
- }
-- ua->jcr->store = store;
-+ set_storage(ua->jcr, store);
-
- if (!relabel && find_arg_keyword(ua, barcode_keyword) >= 0) {
- label_from_barcodes(ua);
-Index: src/dird/ua_run.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-retrieving revision 1.58
-diff -u -r1.58 ua_run.c
---- src/dird/ua_run.c 8 Nov 2004 21:12:12 -0000 1.58
-+++ src/dird/ua_run.c 21 Dec 2004 13:04:11 -0000
-@@ -4,11 +4,11 @@
- *
- * Kern Sibbald, December MMI
- *
-- * Version $Id$
-+ * Version $Id$
- */
-
- /*
-- Copyright (C) 2001-2004 Kern Sibbald and John Walker
-+ Copyright (C) 2001-2004 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
-@@ -42,6 +42,9 @@
- * For Restore Jobs
- * run <job-name> jobid=nn
- *
-+ * Returns: 0 on error
-+ * JobId if OK
-+ *
- */
- int run_cmd(UAContext *ua, const char *cmd)
- {
-@@ -101,7 +104,7 @@
- catalog_name = NULL;
-
- for (i=1; i<ua->argc; i++) {
-- Dmsg2(200, "Doing arg %d = %s\n", i, ua->argk[i]);
-+ Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
- kw_ok = false;
- /* Keep looking until we find a good keyword */
- for (j=0; !kw_ok && kw[j]; j++) {
-@@ -111,12 +114,12 @@
- bsendmsg(ua, _("Value missing for keyword %s\n"), ua->argk[i]);
- return 1;
- }
-- Dmsg1(200, "Got keyword=%s\n", kw[j]);
-+ Dmsg1(800, "Got keyword=%s\n", kw[j]);
- switch (j) {
- case 0: /* job */
- if (job_name) {
- bsendmsg(ua, _("Job name specified twice.\n"));
-- return 1;
-+ return 0;
- }
- job_name = ua->argv[i];
- kw_ok = true;
-@@ -124,7 +127,7 @@
- case 1: /* JobId */
- if (jid) {
- bsendmsg(ua, _("JobId specified twice.\n"));
-- return 1;
-+ return 0;
- }
- jid = ua->argv[i];
- kw_ok = true;
-@@ -133,7 +136,7 @@
- case 3: /* fd */
- if (client_name) {
- bsendmsg(ua, _("Client specified twice.\n"));
-- return 1;
-+ return 0;
- }
- client_name = ua->argv[i];
- kw_ok = true;
-@@ -141,7 +144,7 @@
- case 4: /* fileset */
- if (fileset_name) {
- bsendmsg(ua, _("FileSet specified twice.\n"));
-- return 1;
-+ return 0;
- }
- fileset_name = ua->argv[i];
- kw_ok = true;
-@@ -149,7 +152,7 @@
- case 5: /* level */
- if (level_name) {
- bsendmsg(ua, _("Level specified twice.\n"));
-- return 1;
-+ return 0;
- }
- level_name = ua->argv[i];
- kw_ok = true;
-@@ -158,7 +161,7 @@
- case 7: /* sd */
- if (store_name) {
- bsendmsg(ua, _("Storage specified twice.\n"));
-- return 1;
-+ return 0;
- }
- store_name = ua->argv[i];
- kw_ok = true;
-@@ -166,7 +169,7 @@
- case 8: /* pool */
- if (pool_name) {
- bsendmsg(ua, _("Pool specified twice.\n"));
-- return 1;
-+ return 0;
- }
- pool_name = ua->argv[i];
- kw_ok = true;
-@@ -174,7 +177,7 @@
- case 9: /* where */
- if (where) {
- bsendmsg(ua, _("Where specified twice.\n"));
-- return 1;
-+ return 0;
- }
- where = ua->argv[i];
- kw_ok = true;
-@@ -182,7 +185,7 @@
- case 10: /* bootstrap */
- if (bootstrap) {
- bsendmsg(ua, _("Bootstrap specified twice.\n"));
-- return 1;
-+ return 0;
- }
- bootstrap = ua->argv[i];
- kw_ok = true;
-@@ -190,7 +193,7 @@
- case 11: /* replace */
- if (replace) {
- bsendmsg(ua, _("Replace specified twice.\n"));
-- return 1;
-+ return 0;
- }
- replace = ua->argv[i];
- kw_ok = true;
-@@ -198,7 +201,7 @@
- case 12: /* When */
- if (when) {
- bsendmsg(ua, _("When specified twice.\n"));
-- return 1;
-+ return 0;
- }
- when = ua->argv[i];
- kw_ok = true;
-@@ -206,7 +209,7 @@
- case 13: /* Priority */
- if (Priority) {
- bsendmsg(ua, _("Priority specified twice.\n"));
-- return 1;
-+ return 0;
- }
- Priority = atoi(ua->argv[i]);
- if (Priority <= 0) {
-@@ -221,7 +224,7 @@
- case 15: /* Verify Job */
- if (verify_job_name) {
- bsendmsg(ua, _("Verify Job specified twice.\n"));
-- return 1;
-+ return 0;
- }
- verify_job_name = ua->argv[i];
- kw_ok = true;
-@@ -255,21 +258,22 @@
- Dmsg1(200, "Set jobname=%s\n", job_name);
- } else {
- bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]);
-- return 1;
-+ return 0;
- }
- }
- } /* end argc loop */
-
-- Dmsg0(200, "Done scan.\n");
-+ Dmsg0(800, "Done scan.\n");
-
- CAT *catalog = NULL;
- if (catalog_name != NULL) {
- catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name);
- if (catalog == NULL) {
- bsendmsg(ua, _("Catalog \"%s\" not found\n"), catalog_name);
-- return 1;
-+ return 0;
- }
- }
-+ Dmsg1(200, "Using catalog=%s\n", catalog_name);
-
- if (job_name) {
- /* Find Job */
-@@ -287,11 +291,11 @@
- job = select_job_resource(ua);
- }
- if (!job) {
-- return 1;
-+ return 0;
- } else if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) {
- bsendmsg(ua, _("No authorization. Job \"%s\".\n"),
- job->hdr.name);
-- return 1;
-+ return 0;
- }
-
- if (store_name) {
-@@ -310,8 +314,9 @@
- } else if (!acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
- bsendmsg(ua, _("No authorization. Storage \"%s\".\n"),
- store->hdr.name);
-- return 1;
-+ return 0;
- }
-+ Dmsg1(200, "Using storage=%s\n", store->hdr.name);
-
- if (pool_name) {
- pool = (POOL *)GetResWithName(R_POOL, pool_name);
-@@ -325,12 +330,13 @@
- pool = job->pool; /* use default */
- }
- if (!pool) {
-- return 1;
-+ return 0;
- } else if (!acl_access_ok(ua, Pool_ACL, store->hdr.name)) {
- bsendmsg(ua, _("No authorization. Pool \"%s\".\n"),
- pool->hdr.name);
-- return 1;
-+ return 0;
- }
-+ Dmsg1(200, "Using pool\n", pool->hdr.name);
-
- if (client_name) {
- client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
-@@ -344,12 +350,13 @@
- client = job->client; /* use default */
- }
- if (!client) {
-- return 1;
-+ return 0;
- } else if (!acl_access_ok(ua, Client_ACL, store->hdr.name)) {
- bsendmsg(ua, _("No authorization. Client \"%s\".\n"),
- client->hdr.name);
-- return 1;
-+ return 0;
- }
-+ Dmsg1(200, "Using client=%s\n", client->hdr.name);
-
- if (fileset_name) {
- fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
-@@ -361,11 +368,11 @@
- fileset = job->fileset; /* use default */
- }
- if (!fileset) {
-- return 1;
-+ return 0;
- } else if (!acl_access_ok(ua, FileSet_ACL, store->hdr.name)) {
- bsendmsg(ua, _("No authorization. FileSet \"%s\".\n"),
- fileset->hdr.name);
-- return 1;
-+ return 0;
- }
-
- if (verify_job_name) {
-@@ -386,7 +393,7 @@
- set_jcr_defaults(jcr, job);
-
- jcr->verify_job = verify_job;
-- jcr->store = store;
-+ set_storage(jcr, store);
- jcr->client = client;
- jcr->fileset = fileset;
- jcr->pool = pool;
-@@ -460,7 +467,7 @@
- }
-
- /* Run without prompting? */
-- if (find_arg(ua, _("yes")) > 0) {
-+ if (ua->batch || find_arg(ua, _("yes")) > 0) {
- goto start_job;
- }
-
-@@ -701,7 +708,7 @@
- /* Storage */
- store = select_storage_resource(ua);
- if (store) {
-- jcr->store = store;
-+ set_storage(jcr, store);
- goto try_again;
- }
- break;
-@@ -847,7 +854,7 @@
- } else {
- bsendmsg(ua, _("Job started. JobId=%u\n"), JobId);
- }
-- return 1;
-+ return JobId;
- }
-
- bail_out:
-Index: src/dird/ua_server.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_server.c,v
-retrieving revision 1.35
-diff -u -r1.35 ua_server.c
---- src/dird/ua_server.c 19 Sep 2004 18:56:24 -0000 1.35
-+++ src/dird/ua_server.c 21 Dec 2004 13:04:11 -0000
-@@ -99,6 +99,15 @@
- {
- JCR *jcr;
- jcr = new_jcr(sizeof(JCR), dird_free_jcr);
-+ /*
-+ * The job and defaults are not really used, but
-+ * we set them up to ensure that everything is correctly
-+ * initialized.
-+ */
-+ LockRes();
-+ jcr->job = (JOB *)GetNextRes(R_JOB, NULL);
-+ set_jcr_defaults(jcr, jcr->job);
-+ UnlockRes();
- jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */
- create_unique_job_name(jcr, base_name);
- jcr->sched_time = jcr->start_time;
-@@ -106,20 +115,6 @@
- jcr->JobLevel = L_NONE;
- jcr->JobStatus = JS_Running;
- jcr->JobId = 0;
-- /*
-- * None of these are really defined for control JCRs, so we
-- * simply take the first of each one. This ensures that there
-- * will be no null pointer references.
-- */
-- LockRes();
-- jcr->job = (JOB *)GetNextRes(R_JOB, NULL);
-- jcr->messages = (MSGS *)GetNextRes(R_MSGS, NULL);
-- jcr->client = (CLIENT *)GetNextRes(R_CLIENT, NULL);
-- jcr->pool = (POOL *)GetNextRes(R_POOL, NULL);
-- jcr->catalog = (CAT *)GetNextRes(R_CATALOG, NULL);
-- jcr->store = (STORE *)GetNextRes(R_STORAGE, NULL);
-- jcr->fileset = (FILESET *)GetNextRes(R_FILESET, NULL);
-- UnlockRes();
- return jcr;
- }
-
-Index: src/dird/ua_status.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_status.c,v
-retrieving revision 1.61
-diff -u -r1.61 ua_status.c
---- src/dird/ua_status.c 19 Sep 2004 18:56:25 -0000 1.61
-+++ src/dird/ua_status.c 21 Dec 2004 13:04:12 -0000
-@@ -282,7 +282,7 @@
- {
- BSOCK *sd;
-
-- ua->jcr->store = store;
-+ set_storage(ua->jcr, store);
- /* Try connecting for up to 15 seconds */
- bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d\n"),
- store->hdr.name, store->address, store->SDport);
+++ /dev/null
-
- This patch fixes a bug where a tape gets "truncated" after
- doing a restore. The number of files in the catalog do not
- agree with what Bacula thinks is on tape, then the tape is
- marked in error.
- Apply this patch to version 1.36.1 with:
-
- cd <bacula>
- patch -p0 <1.36.1-truncate.patch
- make
- ...
-
-
---- src/stored/read_record.c.orig 2004-09-29 21:11:17.000000000 +0200
-+++ src/stored/read_record.c 2005-02-15 13:22:12.723140229 +0100
-@@ -266,7 +266,7 @@
- Dmsg2(300, "Current postion (file:block) %d:%d\n",
- dev->file, dev->block_num);
- jcr->bsr->mount_next_volume = false;
-- dev->state |= ST_EOT;
-+// dev->state |= ST_EOT;
- rec->Block = 0;
- return 1;
- }
+++ /dev/null
-
-03Dec04 1.36.1-pool.patch
- This patch should hold jobs in the Director's start queue if
- more than one simultaneous backup job wants to use the same
- Storage device with two different Pools (i.e. 2 Volumes).
-
-03Dec04 1.16.1-slots.patch
- This patch should fix "update slots" with two different magazines
- in different pools by checking the pool when zapping the InChanger.
-
-18Dec04 1.36.1-spool.patch
- This patch fixes the despooling size printed in the Job
- report. Previously, it reported the total size for the
- device. This patch makes it report the size for the job.
-
-21Dec04 1.36.1-store.patch
- This patch fixes a problem with overriding storage daemon
- specifications. Previously they were not always honored.
- This implements more uniform handling. It also eliminates
- an orphaned buffer situation using JobDefs.
-
-21Dec04 1.36.1-reload.patch
- This patch fixes Bacula so that it does not exit if there
- is a syntax error in its conf file during a reload command.
-
-24Dec04 1.36.1-fileset.patch
- This patch should correct a seg fault in the FD that occurs
- at the end of a job when the job uses old style include/excludes.
-
-30Jan05 1.36.1-acl.patch
- This patch fixes some typos with ACL checking that results
- in the incorrect name being used for the check.
- This could lead to security problems with unwanted
- access by restricted consoles.
-
-15Feb05 1.36.1-truncate.patch
- This patch fixes a bug where a tape gets "truncated" after
- doing a restore. The number of files in the catalog do not
- agree with what Bacula thinks is on tape, then the tape is
- marked in error.
+++ /dev/null
-
- This patch causes the output directed to a file to be
- flushed after every line. This is a bit overkill, IMO, but
- a user complained about it.
-
- Apply to 1.36.2 with:
-
- cd <bacula>
- patch -p0 <1.36.2-console.patch
- make
- ...
-
-Index: src/console/console.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/console/console.c,v
-retrieving revision 1.53.6.1
-diff -u -b -r1.53.6.1 console.c
---- src/console/console.c 25 Feb 2005 09:47:06 -0000 1.53.6.1
-+++ src/console/console.c 16 Mar 2005 11:36:43 -0000
-@@ -748,10 +748,11 @@
- }
- #else
- fputs(buf, output);
-+ fflush(output);
- if (tee) {
- fputs(buf, stdout);
- }
-- if (output == stdout || tee) {
-+ if (output != stdout || tee) {
- fflush(stdout);
- }
- #endif
+++ /dev/null
-
- This patch should fix a problem with th %l editing in the
- client (FD) where it edited nothing. With this fix, it should
- edit "since".
- Apply the patch to 1.36.2 with:
-
- cd <bacula-source>
- patch -p0 <1.36.2-level.patch
- make
- ...
-
-Index: src/version.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/version.h,v
-retrieving revision 1.403.2.5
-retrieving revision 1.403.2.5.2.1
-diff -u -r1.403.2.5 -r1.403.2.5.2.1
---- src/version.h 27 Feb 2005 21:54:02 -0000 1.403.2.5
-+++ src/version.h 4 Mar 2005 09:14:15 -0000 1.403.2.5.2.1
-@@ -1,8 +1,8 @@
- /* */
- #undef VERSION
- #define VERSION "1.36.2"
--#define BDATE "28 February 2005"
--#define LSMDATE "28Feb05"
-+#define BDATE "04 March 2005"
-+#define LSMDATE "04Mar05"
-
- /* Debug flags */
- #undef DEBUG
-Index: src/filed/job.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/filed/job.c,v
-retrieving revision 1.91.4.2
-retrieving revision 1.91.4.2.2.1
-diff -u -r1.91.4.2 -r1.91.4.2.2.1
---- src/filed/job.c 25 Feb 2005 09:47:06 -0000 1.91.4.2
-+++ src/filed/job.c 4 Mar 2005 09:14:16 -0000 1.91.4.2.2.1
-@@ -3,7 +3,7 @@
- *
- * Kern Sibbald, October MM
- *
-- * Version $Id$
-+ * Version $Id$
- *
- */
- /*
-@@ -1139,7 +1139,7 @@
- buf = get_memory(dir->msglen+1);
- utime_t since_time, adj;
- btime_t his_time, bt_start, rt=0, bt_adj=0;
-- if (jcr->JobLevel == 0) {
-+ if (jcr->JobLevel == L_NONE) {
- jcr->JobLevel = L_SINCE; /* if no other job level set, do it now */
- }
- if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
+++ /dev/null
-
- This patch corrects a compile problem because of no statfs()
- on NetBSD. The patch was submitted by kardel with bug 258.
-
- Apply the patch to version 1.36.2 with:
-
- cd <bacula>
- patch -p0 <1.36.2-netbsd.patch
- make
- ...
-
-Index: src/findlib/fstype.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/findlib/fstype.c,v
-retrieving revision 1.7.2.2
-diff -u -r1.7.2.2 fstype.c
---- src/findlib/fstype.c 25 Feb 2005 09:47:06 -0000 1.7.2.2
-+++ src/findlib/fstype.c 15 Mar 2005 14:01:44 -0000
-@@ -61,7 +61,6 @@
- */
- #if defined(HAVE_DARWIN_OS) \
- || defined(HAVE_FREEBSD_OS ) \
-- || defined(HAVE_NETBSD_OS) \
- || defined(HAVE_OPENBSD_OS)
-
- #include <sys/param.h>
-@@ -77,7 +76,20 @@
- Dmsg1(50, "statfs() failed for \"%s\"\n", fname);
- return false;
- }
-+#elif defined(HAVE_NETBSD_OS)
-+#include <sys/param.h>
-+#include <sys/mount.h>
-
-+bool fstype(const char *fname, char *fs, int fslen)
-+{
-+ struct statvfs st;
-+ if (statvfs(fname, &st) == 0) {
-+ bstrncpy(fs, st.f_fstypename, fslen);
-+ return true;
-+ }
-+ Dmsg1(50, "statfs() failed for \"%s\"\n", fname);
-+ return false;
-+}
- #elif defined(HAVE_HPUX_OS) \
- || defined(HAVE_IRIX_OS)
-
+++ /dev/null
-
- This patch corrects a problem preventing multiple
- simultaneous jobs from different pools.
- Apply to 1.36.2 with:
-
- cd <bacula-source>
- patch -p0 <1.36.2-pool.patch
- make
- ...
-
-Index: src/dird/jobq.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/jobq.c,v
-retrieving revision 1.25.4.2
-diff -u -r1.25.4.2 jobq.c
---- src/dird/jobq.c 15 Feb 2005 11:51:03 -0000 1.25.4.2
-+++ src/dird/jobq.c 4 Mar 2005 13:16:19 -0000
-@@ -584,7 +584,7 @@
- if (njcr->JobId == 0 || njcr == jcr) {
- continue;
- }
-- if (njcr->pool != jcr->pool) {
-+ if (njcr->store == jcr->store && njcr->pool != jcr->pool) {
- skip_this_jcr = true;
- break;
- }
+++ /dev/null
- This patch should fix a Segfault bug when a job is rescheduled.
- The storage pointers were being released when they should not
- have been.
-
- Apply the patch with:
-
- patch -p0 <1.36.2-reschedule.patch
- make
- ...
-
-Index: src/dird/dird.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/dird.h,v
-retrieving revision 1.7
-diff -u -r1.7 dird.h
---- src/dird/dird.h 19 Apr 2004 14:27:00 -0000 1.7
-+++ src/dird/dird.h 18 Mar 2005 17:39:38 -0000
-@@ -45,3 +45,4 @@
-
- /* From job.c */
- void dird_free_jcr(JCR *jcr);
-+void dird_free_jcr_pointers(JCR *jcr);
-Index: src/dird/job.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/job.c,v
-retrieving revision 1.92.2.2
-diff -u -r1.92.2.2 job.c
---- src/dird/job.c 27 Feb 2005 21:53:28 -0000 1.92.2.2
-+++ src/dird/job.c 18 Mar 2005 17:39:38 -0000
-@@ -676,15 +676,9 @@
- }
- }
-
--/*
-- * Free the Job Control Record if no one is still using it.
-- * Called from main free_jcr() routine in src/lib/jcr.c so
-- * that we can do our Director specific cleanup of the jcr.
-- */
--void dird_free_jcr(JCR *jcr)
-+/* Called directly from job rescheduling */
-+void dird_free_jcr_pointers(JCR *jcr)
- {
-- Dmsg0(200, "Start dird free_jcr\n");
--
- if (jcr->sd_auth_key) {
- free(jcr->sd_auth_key);
- jcr->sd_auth_key = NULL;
-@@ -723,7 +717,21 @@
- }
- if (jcr->term_wait_inited) {
- pthread_cond_destroy(&jcr->term_wait);
-+ jcr->term_wait_inited = false;
- }
-+}
-+
-+/*
-+ * Free the Job Control Record if no one is still using it.
-+ * Called from main free_jcr() routine in src/lib/jcr.c so
-+ * that we can do our Director specific cleanup of the jcr.
-+ */
-+void dird_free_jcr(JCR *jcr)
-+{
-+ Dmsg0(200, "Start dird free_jcr\n");
-+
-+ dird_free_jcr_pointers(jcr);
-+
- /* Delete lists setup to hold storage pointers */
- for (int i=0; i<MAX_STORE; i++) {
- if (jcr->storage[i]) {
-Index: src/dird/jobq.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/jobq.c,v
-retrieving revision 1.25.4.2
-diff -u -r1.25.4.2 jobq.c
---- src/dird/jobq.c 15 Feb 2005 11:51:03 -0000 1.25.4.2
-+++ src/dird/jobq.c 18 Mar 2005 17:39:38 -0000
-@@ -481,7 +481,7 @@
- bstrftime(dt, sizeof(dt), time(NULL));
- Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds.\n"),
- jcr->Job, dt, (int)jcr->job->RescheduleInterval);
-- dird_free_jcr(jcr); /* partial cleanup old stuff */
-+ dird_free_jcr_pointers(jcr); /* partial cleanup old stuff */
- jcr->JobStatus = JS_WaitStartTime;
- jcr->SDJobStatus = 0;
- if (jcr->JobBytes == 0) {
+++ /dev/null
-
- This patch will fix a subtle bug that was introduced in 1.36.2
- which causes Bacula to be very slow restoring a few files. This
- is because it reads completely to the end of the Volume rather
- than stopping when all the files on the Volume are loaded. The
- introduction of the bug was caused by a patch that fixed
- Bacula truncating tapes after a restore.
-
- Apply the patch to 1.36.2 with the following:
-
- cd <bacula-source>
- patch -p0 <1.36.2-restore-speed.patch
- make
- ...
-
- Note that all source files will be rebuilt during the make.
-
-Index: src/jcr.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/jcr.h,v
-retrieving revision 1.76.4.1
-diff -u -u -b -r1.76.4.1 jcr.h
---- src/jcr.h 27 Feb 2005 21:53:28 -0000 1.76.4.1
-+++ src/jcr.h 17 Mar 2005 14:14:18 -0000
-@@ -243,6 +243,7 @@
-
- /* Parmaters for Open Read Session */
- BSR *bsr; /* Bootstrap record -- has everything */
-+ bool mount_next_volume; /* set to cause next volume mount */
- uint32_t read_VolSessionId;
- uint32_t read_VolSessionTime;
- uint32_t read_StartFile;
-Index: src/stored/read_record.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/read_record.c,v
-retrieving revision 1.47.4.1
-diff -u -u -b -r1.47.4.1 read_record.c
---- src/stored/read_record.c 15 Feb 2005 11:51:04 -0000 1.47.4.1
-+++ src/stored/read_record.c 17 Mar 2005 14:14:18 -0000
-@@ -5,13 +5,16 @@
- * archive. It uses a callback to pass you each record in turn,
- * as well as a callback for mounting the next tape. It takes
- * care of reading blocks, applying the bsr, ...
-+ * Note, this routine is really the heart of the restore routines,
-+ * and we are *really* bit pushing here so be careful about making
-+ * any modifications.
- *
- * Kern E. Sibbald, August MMII
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
-- Copyright (C) 2000-2004 Kern Sibbald and John Walker
-+ Copyright (C) 2000-2005 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
-@@ -57,6 +60,7 @@
-
- recs = New(dlist(rec, &rec->link));
- position_to_first_file(jcr, dev);
-+ jcr->mount_next_volume = false;
-
- for ( ; ok && !done; ) {
- if (job_canceled(jcr)) {
-@@ -66,12 +70,11 @@
- if (!read_block_from_device(dcr, CHECK_BLOCK_NUMBERS)) {
- if (dev->at_eot()) {
- DEV_RECORD *trec = new_record();
--
- Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n",
- dev->file, dev_name(dev), dcr->VolumeName);
- if (!mount_cb(dcr)) {
- Jmsg(jcr, M_INFO, 0, "End of all volumes.\n");
-- ok = false;
-+ ok = false; /* Stop everything */
- /*
- * Create EOT Label so that Media record may
- * be properly updated because this is the last
-@@ -81,8 +84,13 @@
- trec->File = dev->file;
- ok = record_cb(dcr, trec);
- free_record(trec);
-+ if (jcr->mount_next_volume) {
-+ jcr->mount_next_volume = false;
-+ dev->state &= ~ST_EOT;
-+ }
- break;
- }
-+ jcr->mount_next_volume = false;
- /*
- * We just have a new tape up, now read the label (first record)
- * and pass it off to the callback routine, then continue
-@@ -113,10 +121,10 @@
- display_tape_error_status(jcr, dev);
- if (forge_on || jcr->ignore_label_errors) {
- fsr_dev(dev, 1); /* try skipping bad record */
-- Dmsg0(000, "Did fsr\n");
-+ Pmsg0(000, "Did fsr\n");
- continue; /* try to continue */
- }
-- ok = false;
-+ ok = false; /* stop everything */
- break;
- }
- }
-@@ -259,7 +267,11 @@
- Dmsg2(300, "Current postion (file:block) %d:%d\n",
- dev->file, dev->block_num);
- jcr->bsr->mount_next_volume = false;
--// dev->state |= ST_EOT;
-+ if (!dev->at_eot()) {
-+ /* Set EOT flag to force mount of next Volume */
-+ jcr->mount_next_volume = true;
-+ dev->state |= ST_EOT;
-+ }
- rec->Block = 0;
- return 1;
- }
+++ /dev/null
-
- This patch fails a job if no Storage resource is specified and
- the job attempts to call the SD.
-
- Apply the patch to 1.36.2 with:
-
- cd <bacula-source>
- patch -p0 <1.36.2-store.patch
- make
- ...
-
-Index: src/dird/msgchan.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/msgchan.c,v
-retrieving revision 1.32.4.1
-diff -u -r1.32.4.1 msgchan.c
---- src/dird/msgchan.c 14 Feb 2005 10:02:21 -0000 1.32.4.1
-+++ src/dird/msgchan.c 18 Mar 2005 15:40:53 -0000
-@@ -66,6 +66,10 @@
- BSOCK *sd;
- STORE *store;
-
-+ if (!jcr->storage[0]) {
-+ Jmsg(jcr, M_FATAL, 0, _("Attempt to contact the Storage daemon with no Storage resource.\n"));
-+ return false;
-+ }
- store = (STORE *)jcr->storage[0]->first();
-
- /*
+++ /dev/null
-
- This patch should fix memory leaks in tray-monitor.
- Apply the patch to 1.36.2 with:
-
- cd <bacula-source>/src/tray-monitor
- patch -p0 <1.36.2-tray-monitor-memleak.patch
- make
- ...
-
-Index: tray-monitor.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-retrieving revision 1.19
-diff -r1.19 tray-monitor.c
-36a37,38
-> #define TRAY_DEBUG_MEMORY 0
->
-50d51
-< static POOLMEM *args;
-135a137,157
-> int sm_line = 0;
->
-> #if TRAY_DEBUG_MEMORY
-> gpointer smt_malloc(gsize n_bytes) {
-> return sm_malloc("GLib", sm_line, n_bytes);
-> }
->
-> gpointer smt_realloc(gpointer mem, gsize n_bytes) {
-> return sm_realloc("GLib", sm_line, mem, n_bytes);
-> }
->
-> gpointer smt_calloc(gsize n_blocks,
-> gsize n_block_bytes) {
-> return sm_calloc("GLib", sm_line, n_blocks, n_block_bytes);
-> }
->
-> void smt_free(gpointer mem) {
-> sm_free("Glib", sm_line, mem);
-> }
-> #endif
->
-142a165,175
-> #if TRAY_DEBUG_MEMORY
-> GMemVTable smvtable;
-> smvtable.malloc = &smt_malloc;
-> smvtable.realloc = &smt_realloc;
-> smvtable.free = &smt_free;
-> smvtable.calloc = &smt_calloc;
-> smvtable.try_malloc = NULL;
-> smvtable.try_realloc = NULL;
-> g_mem_set_vtable(&smvtable);
-> #endif
->
-154d186
-< args = get_pool_memory(PM_FNAME);
-255c287
-< g_assert((xpm_generic_var[i] = (char*)g_malloc(strlen(xpm_generic[i])*sizeof(char))));
----
-> g_assert((xpm_generic_var[i] = (char*)g_malloc((strlen(xpm_generic[i])+1)*sizeof(char))));
-412a445,448
->
-> g_source_remove(timerTag);
->
-> sm_line = 0;
-422d457
-< free_pool_memory(args);
-429a465,468
->
-> gtk_object_destroy(GTK_OBJECT(window));
-> gtk_object_destroy(GTK_OBJECT(mTrayMenu));
-> term_msg();
-430a470,473
-> #if TRAY_DEBUG_MEMORY
-> sm_dump(false);
-> #endif
->
-534c577,581
-< GtkTextBuffer *newbuffer = gtk_text_buffer_new(NULL);
----
-> sm_line++;
-> #if TRAY_DEBUG_MEMORY
-> printf("sm_line=%d\n", sm_line);
-> #endif
-> GtkTextBuffer *newbuffer;
-546a594,595
-> newbuffer = gtk_text_buffer_new(NULL);
->
-558a608,609
-> g_slist_free(list);
->
-963a1015
-> g_object_unref(G_OBJECT(pixbuf));
+++ /dev/null
-
- This patch will prevent the Win32 FD from printing an error message
- when it attempts to restore the permissions for a drive (which Win32
- doesn't permit). The error is harmless in any case.
- Apply the patch to 1.36.2 with
-
- cd <bacula-source>
- patch -p0 <1.36.2-win32-drive.patch
- make
- ...<F12>
-
-
-Index: src/findlib/create_file.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/findlib/create_file.c,v
-retrieving revision 1.34
-diff -u -r1.34 create_file.c
---- src/findlib/create_file.c 27 Jul 2004 21:00:33 -0000 1.34
-+++ src/findlib/create_file.c 9 Mar 2005 17:52:50 -0000
-@@ -271,6 +271,12 @@
- if ((bopen(bfd, attr->ofname, O_WRONLY|O_BINARY, 0)) < 0) {
- berrno be;
- be.set_errno(bfd->berrno);
-+#ifdef HAVE_WIN32
-+ /* Check for trying to create a drive, if so, skip */
-+ if (attr->ofname[1] == ':' && attr->ofname[2] == '/' && attr->ofname[3] == 0) {
-+ return CF_SKIP;
-+ }
-+#endif
- Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"),
- attr->ofname, be.strerror());
- return CF_ERROR;
+++ /dev/null
-Index: CHANGELOG
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/wx-console/CHANGELOG,v
-retrieving revision 1.42.8.2
-retrieving revision 1.42
-diff -r1.42.8.2 -r1.42
-1,9d0
-< 24-03-2005 :
-< - wxbMainFrame : Fix a bug with GTK+-1.2 which caused wx-console to crash
-< when starting.
-< - wxbRestorePanel : Fix a major bug which caused wx-console to enter in an
-< infinite loop which allocate a lot of memory and could make the system crash.
-<
-< 10-03-2005 :
-< - wxbMainFrame : Fix bug #0000221 (Debian 292517)
-<
-Index: wxbmainframe.cpp
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/wx-console/wxbmainframe.cpp,v
-retrieving revision 1.30.6.2
-retrieving revision 1.30
-diff -r1.30.6.2 -r1.30
-7c7
-< * Version $Id$
----
-> * Version $Id$
-210,211d209
-< lockedbyconsole = false;
-<
-317a316,317
-> lockedbyconsole = false;
->
-650,651c650,651
-< if (res == -1) { //Cancel pressed
-< Send(".\n");
----
-> if (res == -1) {
-> Send("\n");
-Index: wxbrestorepanel.cpp
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/wx-console/wxbrestorepanel.cpp,v
-retrieving revision 1.40.8.1
-retrieving revision 1.40
-diff -r1.40.8.1 -r1.40
-7c7
-< * Version $Id$
----
-> * Version $Id$
-411c411
-< markWhenCommandDone = false;
----
-> markWhenListingDone = false;
-1987a1988
-> AddPendingEvent(event);
-1996a1998
-> AddPendingEvent(event);
-2002a2005
-> AddPendingEvent(event);
-2015a2019
-> AddPendingEvent(event);
-2024c2028
-< markWhenCommandDone = false;
----
-> markWhenListingDone = false;
-2028c2032
-< if (markWhenCommandDone) {
----
-> if (markWhenListingDone) {
-2041a2046
-> csprint("Tree marked", CS_DEBUG);
-2044c2049
-< markWhenCommandDone = !markWhenCommandDone;
----
-> markWhenListingDone = !markWhenListingDone;
-2045a2051
-> AddPendingEvent(event);
-2049d2054
-< markWhenCommandDone = false;
-2051,2054c2056
-< if (markWhenCommandDone) {
-< CmdMark(event.GetItem(), NULL, 0);
-< tree->Refresh();
-< }
----
-> //event.Skip();
-2065a2068
-> AddPendingEvent(event);
-2080a2084
-> AddPendingEvent(event);
-2095a2100
-> AddPendingEvent(event);
-2105a2111,2112
-> AddPendingEvent(event);
-> //event.Skip();
-2125c2132
-<
----
->
-2140a2148,2149
-> AddPendingEvent(event);
-> //event.Skip();
-2176a2186
-> AddPendingEvent(event);
-2212a2223
-> AddPendingEvent(event);
-2241a2253
-> AddPendingEvent(event);
-2270a2283
-> AddPendingEvent(event);
-Index: wxbrestorepanel.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/wx-console/wxbrestorepanel.h,v
-retrieving revision 1.19.10.1
-retrieving revision 1.19
-diff -r1.19.10.1 -r1.19
-7c7
-< * Version $Id$
----
-> * Version $Id$
-154c154
-< bool markWhenCommandDone; //If an item should be (un)marked after the current listing/marking is done
----
-> bool markWhenListingDone;
+++ /dev/null
-
-04Mar05 1.36.2-level.patch
- This patch should fix a problem with th %l editing in the
- client (FD) where it edited nothing. With this fix, it should
- edit "since".
-
-04Mar05 1.36.2-pool.patch
- This patch corrects a problem preventing multiple
- simultaneous jobs from different pools.
-
-09Mar05 1.36.2-win32-drive.patch
- This patch will prevent the Win32 FD from printing an error message
- when it attempts to restore the permissions for a drive (which Win32
- doesn't permit). The error is harmless in any case.
-
-15Mar05 1.36.2-netbsd.patch
- This patch corrects a compile problem because of no statfs()
- on NetBSD. The patch was submitted by kardel with bug 258.
-
-16Mar05 1.36.2-console.patch
- This patch causes the output directed to a file to be
- flushed after every line. This is a bit overkill, IMO, but
- a user complained about it.
-
-17Mar05 1.36.2-restore-speed.patch
- This patch will fix a subtle bug that was introduced in 1.36.2
- which causes Bacula to be very slow restoring a few files. This
- is because it reads completely to the end of the Volume rather
- than stopping when all the files on the Volume are loaded. The
- introduction of the bug was caused by a patch that fixed
- Bacula truncating tapes after a restore.
- Note that all source files will be rebuilt during the make.
-
-18Mar05 1.36.2-store.patch
- This patch fails a job if no Storage resource is specified and
- the job attempts to call the SD.
-
-18Mar05 1.36.2-reschedule.patch
- This patch should fix a Segfault bug when a job is rescheduled.
- The storage pointers were being released when they should not
- have been.
-
-24Mar05 1.36.2-wx-console-bugfixes.patch
- Major wx-console fixes (see src/wx-console/CHANGELOG for details).
-
-28Mar05 1.36.2-tray-monitor-memleak.patch
- This patch should fix memory leaks in tray-monitor.
+++ /dev/null
-Index: src/tray-monitor/tray-monitor.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-retrieving revision 1.21
-diff -r1.21 tray-monitor.c
-455c455,468
-< writecmd(&items[i], "quit");
----
-> switch (items[i].type) {
-> case R_DIRECTOR:
-> trayMessage("Disconnecting from Director %s:%d\n", ((DIRRES*)items[i].resource)->address, ((DIRRES*)items[i].resource)->DIRport);
-> break;
-> case R_CLIENT:
-> trayMessage("Disconnecting from Client %s:%d\n", ((CLIENT*)items[i].resource)->address, ((CLIENT*)items[i].resource)->FDport);
-> break;
-> case R_STORAGE:
-> trayMessage("Disconnecting from Storage %s:%d\n", ((STORE*)items[i].resource)->address, ((STORE*)items[i].resource)->SDport);
-> break;
-> default:
-> break;
-> }
-> //writecmd(&items[i], "quit");
+++ /dev/null
-Index: src/wx-console/wxbrestorepanel.cpp
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/wx-console/wxbrestorepanel.cpp,v
-retrieving revision 1.40.8.1
-diff -u -r1.40.8.1 wxbrestorepanel.cpp
---- src/wx-console/wxbrestorepanel.cpp 24 Mar 2005 14:52:55 -0000 1.40.8.1
-+++ src/wx-console/wxbrestorepanel.cpp 5 May 2005 18:45:05 -0000
-@@ -1469,23 +1469,29 @@
- wxString* wxbRestorePanel::ParseList(wxString line) {
- /* See ls_output in dird/ua_tree.c */
-
-- //drwxrwxrwx 1 root root 0 2004-04-03 14:35:21 f:/tocd/NVSU 1.00.00/
-- //+ 10 + ++ + 8 + + 8 ++ 8 + + 19 + *+ ->
-- //0 12 15 24 32 42 62
--
-+ //drwxrwxrwx 111 root root 0 2004-04-03 14:35:21 f:/tocd/NVSU 1.00.00/
-+ //+ 10 + +i+ + 8 + + 8 ++ 8 + + 19 + *+ ->
-+ //0 12 i+15 i+24 i+32 i+42 i+62
-+
-+ int i;
-+
- if (line.Length() < 63)
- return NULL;
-
- wxString* ret = new wxString[9];
-
- ret[0] = line.Mid(0, 10).Trim();
-- ret[1] = line.Mid(12, 2).Trim();
-- ret[2] = line.Mid(15, 8).Trim();
-- ret[3] = line.Mid(24, 8).Trim();
-- ret[4] = line.Mid(32, 8).Trim();
-- ret[5] = line.Mid(42, 19).Trim();
-- ret[6] = line.Mid(62, 1);
-- ret[7] = line.Mid(63).Trim();
-+
-+ /* Column 1 has a variable width */
-+ i = line.find(' ', 14) - 14;
-+ ret[1] = line.Mid(12, 2+i).Trim();
-+
-+ ret[2] = line.Mid(15+i, 8).Trim();
-+ ret[3] = line.Mid(24+i, 8).Trim();
-+ ret[4] = line.Mid(32+i, 8).Trim();
-+ ret[5] = line.Mid(42+i, 19).Trim();
-+ ret[6] = line.Mid(62+i, 1);
-+ ret[7] = line.Mid(63+i).Trim();
-
- if (ret[6] == " ") ret[6] = "";
-
+++ /dev/null
-05May05 1.36.3-wx-console-fix-dir-alignment.diff
- Fix a problem when link count for a file is greater than 99 (bug #304).
-
-25Apr05 1.36.3-tray-monitor-fix-broken-pipe.diff
- Fix broken pipe when closing bacula-tray-monitor (bug #292).
+++ /dev/null
-
- This patch fixes the following bugs:
-
-- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
- says that this patch does not fix his problem)
-- Fix cancel failure bug. Bug #481
-- Fix failure when Pool name has spaces. Bug #487
-- Fix SD crash in autochanger code. Mutex failure. Bug #488
-- Fix a couple of free()s in src/filed/acl.c
-- Fix memory overrun in bfile.c in building OS X resource
- fork filename. Bug #489
-- Add Pool name to SD status output.
-- Add Python install dir for Solaris to configure. Bug #492
-
-This patch is applied to Bacula source version 1.38.1 and will
-produce Bacula source version 1.38.2. Apply it with:
-
- cd <bacula-1.38.1-source>
- ./configure (your options) if not already done
- patch -p0 <1.38.1-to-1.38.2.patch
- make
- make install
-
-Index: ChangeLog
-===================================================================
-RCS file: /cvsroot/bacula/bacula/ChangeLog,v
-retrieving revision 1.154.2.7
-retrieving revision 1.154.2.8
-diff -u -r1.154.2.7 -r1.154.2.8
---- ChangeLog 15 Nov 2005 09:27:19 -0000 1.154.2.7
-+++ ChangeLog 22 Nov 2005 10:50:54 -0000 1.154.2.8
-@@ -1,4 +1,15 @@
-
-+Changes to 1.38.2:
-+- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+- Fix bnet-server bug found on OpenBSD. Bug #486
-+- Fix cancel failure bug. Bug #481
-+- Fix failure when Pool name has spaces. Bug #487
-+- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+- Fix a couple of free()s in src/filed/acl.c
-+- Fix memory overrun in bfile.c in building OS X resource
-+ fork filename. Bug #489
-+- Add Pool name to SD status output.
-+- Add Python install dir for Solaris to configure. Bug #492
-
- Changes to 1.38.1:
- - Apply SunOS patch for ACLs submitted by David Duchscher.
-Index: ReleaseNotes
-===================================================================
-RCS file: /cvsroot/bacula/bacula/ReleaseNotes,v
-retrieving revision 1.147.2.9
-retrieving revision 1.147.2.10
-diff -u -r1.147.2.9 -r1.147.2.10
---- ReleaseNotes 15 Nov 2005 09:27:19 -0000 1.147.2.9
-+++ ReleaseNotes 22 Nov 2005 10:50:54 -0000 1.147.2.10
-@@ -1,10 +1,22 @@
-
-- Release Notes for Bacula 1.38.1
-+ Release Notes for Bacula 1.38.2
-
- Bacula code: Total files = 420 Total lines = 138,440 (*.h *.c *.in)
- 20,440 additional lines of code since version 1.36.3
-
--Changes since 1.38.0:
-+Changes to 1.38.2:
-+- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+- Fix bnet-server bug found on OpenBSD. Bug #486
-+- Fix cancel failure bug. Bug #481
-+- Fix failure when Pool name has spaces. Bug #487
-+- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+- Fix a couple of free()s in src/filed/acl.c
-+- Fix memory overrun in bfile.c in building OS X resource
-+ fork filename. Bug #489
-+- Add Pool name to SD status output.
-+- Add Python install dir for Solaris to configure. Bug #492
-+
-+Changes to 1.38.1:
- - Corrected ACL for Solaris (David Duchscher and Attila Fulop).
- - Add bacula_mail_summary.sh to examples directory. It makes
- a single email summary of any number of jobs. Submitted
-Index: configure
-===================================================================
-RCS file: /cvsroot/bacula/bacula/configure,v
-retrieving revision 1.203.2.5
-retrieving revision 1.203.2.6
-diff -u -r1.203.2.5 -r1.203.2.6
---- configure 13 Nov 2005 10:51:17 -0000 1.203.2.5
-+++ configure 22 Nov 2005 10:50:54 -0000 1.203.2.6
-@@ -14948,7 +14948,7 @@
- PYTHON_LIBS=
- if test "$withval" != "no"; then
- if test "$withval" = "yes"; then
-- for python_root in /usr /usr/local; do
-+ for python_root in /usr /usr/local /usr/sfw; do
- if test -f $python_root/include/python2.2/Python.h; then
- PYTHON_INCDIR=-I$python_root/include/python2.2
- PYTHON_LIBS="-L$python_root/lib/python2.2/config -lpython2.2"
-Index: kernstodo
-===================================================================
-RCS file: /cvsroot/bacula/bacula/kernstodo,v
-retrieving revision 1.570.2.6
-retrieving revision 1.570.2.7
-diff -u -r1.570.2.6 -r1.570.2.7
---- kernstodo 4 Nov 2005 09:16:49 -0000 1.570.2.6
-+++ kernstodo 22 Nov 2005 10:50:55 -0000 1.570.2.7
-@@ -1,5 +1,5 @@
- Kern's ToDo List
-- 03 November 2005
-+ 21 November 2005
-
- Major development:
- Project Developer
-@@ -7,8 +7,6 @@
- Version 1.37 Kern (see below)
- ========================================================
-
--Final items for 1.37 before release:
--
- Document:
- - Does ClientRunAfterJob fail the job on a bad return code?
- - Document cleaning up the spool files:
-@@ -18,6 +16,8 @@
- - Does WildFile match against full name? Doc.
-
- For 1.39:
-+- Make sure that all do_prompt() calls in Dir check for
-+ -1 (error) and -2 (cancel) returns.
- - Look at -D_FORTIFY_SOURCE=2
- - Add Win32 FileSet definition somewhere
- - Look at fixing restore status stats in SD.
-@@ -27,6 +27,12 @@
- encountered, read many times (as it currently does), and if the
- block cannot be read, skip to the next block, and try again. If
- that fails, skip to the next file and try again, ...
-+- Add level table:
-+ create table LevelType (LevelType binary(1), LevelTypeLong tinyblob);
-+ insert into LevelType (LevelType,LevelTypeLong) values
-+ ("F","Full"),
-+ ("D","Diff"),
-+ ("I","Inc");
- - Add ACL to restore only to original location.
- - Add a recursive mark command (rmark) to restore.
- - "Minimum Job Interval = nnn" sets minimum interval between Jobs
-@@ -1246,219 +1252,4 @@
- ====
-
-
--=== Done
--- Save mount point for directories not traversed with onefs=yes.
--- Add seconds to start and end times in the Job report output.
--- if 2 concurrent backups are attempted on the same tape
-- drive (autoloader) into different tape pools, one of them will exit
-- fatally instead of halting until the drive is idle
--- Update StartTime if job held in Job Queue.
--- Look at www.nu2.nu/pebuilder as a helper for full windows
-- bare metal restore. (done by Scott)
--- Fix orphanned buffers:
-- Orphaned buffer: 24 bytes allocated at line 808 of rufus-dir job.c
-- Orphaned buffer: 40 bytes allocated at line 45 of rufus-dir alist.c
--- Implement Preben's suggestion to add
-- File System Types = ext2, ext3
-- to FileSets, thus simplifying backup of *all* local partitions.
--- Try to open a device on each Job if it was not opened
-- when the SD started.
--- Add dump of VolSessionId/Time and FileIndex with bls.
--- If Bacula does not find the right tape in the Autochanger,
-- then mark the tape in error and move on rather than asking
-- for operator intervention.
--- Cancel command should include JobId in list of Jobs.
--- Add performance testing hooks
--- Bootstrap from JobMedia records.
--- Implement WildFile and WildDir to solve problem of
-- saving only *.doc files.
--- Fix
-- Please use the "label" command to create a new Volume for:
-- Storage: DDS-4-changer
-- Media type:
-- Pool: Default
-- label
-- The defined Storage resources are:
--- Copy Changer Device and Changer Command from Autochanger
-- to Device resource in SD if none given in Device resource.
--- 1. Automatic use of more than one drive in an autochanger (done)
--- 2. Automatic selection of the correct drive for each Job (i.e.
-- selects a drive with an appropriate Volume for the Job) (done)
--- 6. Allow multiple simultaneous Jobs referencing the same pool write
-- to several tapes (some new directive(s) are are probably needed for
-- this) (done)
--- Locking (done)
--- Key on Storage rather than Pool (done)
--- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
--- Synchronize multiple drives so that not more
-- than one loads a tape and any time (done)
--- 4. Use Changer Device and Changer Command specified in the
-- Autochanger resource, if none is found in the Device resource.
-- You can continue to specify them in the Device resource if you want
-- or need them to be different for each device.
--- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
-- that can allow a Device be part of an Autochanger, and hence the changer
-- script protected, but if set to no, will prevent the Device from being
-- automatically selected from the changer. This allows the device to
-- be directly accessed through its Device name, but not through the
-- AutoChanger name.
--#6 Select one from among Multiple Storage Devices for Job
--#5 Events that call a Python program
-- (Implemented in Dir/SD)
--- Make sure the Device name is in the Query packet returned.
--- Don't start a second file job if one is already running.
--- Implement EOF/EOV labels for ANSI labels
--- Implement IBM labels.
--- When Python creates a new label, the tape is immediately
-- recycled and no label created. This happens when using
-- autolabeling -- even when Python doesn't generate the name.
--- Scratch Pool where the volumes can be re-assigned to any Pool.
--- 28-Mar 23:19 rufus-sd: acquire.c:379 Device "DDS-4" (/dev/nst0)
-- is busy reading. Job 6 canceled.
--- Remove separate thread for opening devices in SD. On the other
-- hand, don't block waiting for open() for devices.
--- Fix code to either handle updating NumVol or to calculate it in
-- Dir next_vol.c
--- Ensure that you cannot exclude a directory or a file explicitly
-- Included with File.
--#4 Embedded Python Scripting
-- (Implemented in Dir/SD/FD)
--- Add Python writable variable for changing the Priority,
-- Client, Storage, JobStatus (error), ...
--- SD Python
-- - Solicit Events
--- Add disk seeking on restore; turn off seek on tapes.
-- stored/match_bsr.c
--- Look at dird_conf.c:1000: warning: `int size'
-- might be used uninitialized in this function
--- Indicate when a Job is purged/pruned during restore.
--- Implement some way to turn off automatic pruning in Jobs.
--- Implement a way an Admin Job can prune, possibly multiple
-- clients -- Python script?
--- Look at Preben's acl.c error handling code.
--- SD crashes after a tape restore then doing a backup.
--- If drive is opened read/write, close it and re-open
-- read-only if doing a restore, and vice-versa.
--- Windows restore:
-- data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
-- > ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
-- > Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen
-- > Prozess verwendet wird.
-- Restore restores all files, but then fails at the end trying
-- to set the attributes of e:
-- from failed jobs.- Resolve the problem between Device name and Archive name,
-- and fix SD messages.
--- Tell the "restore" user when browsing is no longer possible.
--- Add a restore directory-x
--- Write non-optimized bsrs from the JobMedia and Media records,
-- even after Files are pruned.
--- Delete Stripe and Copy from VolParams to save space.
--- Fix option 2 of restore -- list where file is backed up -- require Client,
-- then list last 20 backups.
--- Finish implementation of passing all Storage and Device needs to
-- the SD.
--- Move test for max wait time exceeded in job.c up -- Peter's idea.
--## Consider moving docs to their own project.
--## Move rescue to its own project.
--- Add client version to the Client name line that prints in
-- the Job report.
--- Fix the Rescue CDROM.
--- By the way: on page http://www.bacula.org/?page=tapedrives , at the
-- bottom, the link to "Tape Testing Chapter" is broken. It goes to
-- /html-manual/... while the others point to /rel-manual/...
--- Device resource needs the "name" of the SD.
--- Specify a single directory to restore.
--- Implement MediaType keyword in bsr?
--- Add a date and time stamp at the beginning of every line in the
-- Job report (Volker Sauer).
--- Add level to estimate command.
--- Add "limit=n" for "list jobs"
--- Make bootstrap filename unique.
--- Make Dmsg look at global before calling subroutine.
--- From Chris Hull:
-- it seems to be complaining about 12:00pm which should be a valid 12
-- hour time. I changed the time to 11:59am and everything works fine.
-- Also 12:00am works fine. 0:00pm also works (which I don't think
-- should). None of the values 12:00pm - 12:59pm work for that matter.
--- Require restore via the restore command or make a restore Job
-- get the bootstrap file.
--- Implement Maximum Job Spool Size
--- Fix 3993 error in SD. It forgets to look at autochanger
-- resource for device command, ...
--- 3. Prevent two drives requesting the same Volume in any given
-- autochanger, by checking if a Volume is mounted on another drive
-- in an Autochanger.
--- Upgrade to MySQL 4.1.12 See:
-- http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
--- Add # Job Level date to bsr file
--- Implement "PreferMountedVolumes = yes|no" in Job resource.
--## Integrate web-bacula into a new Bacula project with
-- bimagemgr.
--- Cleaning tapes should have Status "Cleaning" rather than append.
--- Make sure that Python has access to Client address/port so that
-- it can check if Clients are alive.
--- Review all items in "restore".
--- Fix PostgreSQL GROUP BY problems in restore.
--- Fix PostgreSQL sql problems in bugs.
--- After rename
-- 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume
-- "DLT-13Feb04".
-- Current Volume "DLT-04Jul05" not acceptable because:
-- 1997 Volume "DLT-13Feb04" not in catalog.
-- 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device
-- "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
--## Create a new GUI chapter explaining all the GUI programs.
--- Make "update slots" when pointing to Autochanger, remove
-- all Volumes from other drives. "update slots all-drives"?
-- No, this is done by modifying mtx-changer to list what is
-- in the drives.
--- Finish TLS implementation.
--- Port limiting -m in iptables to prevent DoS attacks
-- could cause broken pipes on Bacula.
--6. Build and test the Volume Shadow Copy (VSS) for Win32.
--- Allow cancel of unknown Job
--- State not saved when closing Win32 FD by icon
--- bsr-opt-test fails. bsr deleted. Fix.
--- Move Python daemon variables from Job to Bacula object.
-- WorkingDir, ConfigFile
--- Document that Bootstrap files can be written with cataloging
-- turned off.
--- Document details of ANSI/IBM labels
--- OS linux 2.4
-- 1) ADIC, DLT, FastStor 4000, 7*20GB
--- Linux Sony LIB-D81, AIT-3 library works.
--- Doc the following
-- to activate, check or disable the hardware compression feature on my
-- exb-8900 i use the exabyte "MammothTool" you can get it here:
-- http://www.exabyte.com/support/online/downloads/index.cfm
-- There is a solaris version of this tool. With option -C 0 or 1 you can
-- disable or activate compression. Start this tool without any options for
-- a small reference.
--- Document Heartbeat Interval in the dealing with firewalls section.
--- Document new CDROM directory.
--- On Win32 working directory must have drive letter ????
--- On Win32 working directory must be writable by SYSTEM to
-- do restores.
--- Document that ChangerDevice is used for Alert command.
--- Add better documentation on how restores can be done
--8. Take one more try at making DVD writing work (no go)
--7. Write a bacula-web document
--- Why isn't the DEVICE structure defined when doing
-- a reservation?
--- Multi-drive changer seems to only use drive 0
-- Multiple drives don't seem to be opened.
--- My database is growing
--- Call GetLastError() in the berrno constructor rather
-- than delaying until strerror.
--- Tape xxx in drive 0, requested in drive 1
--- The mount command does not work with drives other than 0.
--- A mount should cause the SD to re-examine what Slot is
-- loaded.
--- The SD locks on to the first available drive then
-- wants a Volume that is released but in another drive --
-- chaos.
--- Run the regression scripts on Solaris and FreeBSD
--- Figure out how to package gui, and rescue programs.
--- Add a .dir command to restore tree code to eliminate the problem
--- Mount after manually unloading changer causes hang in SD
--- Fix JobACL with restore by JobId.
-+=== Done -- see kernsdone
-Index: kes-1.38
-===================================================================
-RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-retrieving revision 1.1.2.13
-retrieving revision 1.1.2.14
-diff -u -r1.1.2.13 -r1.1.2.14
---- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-+++ kes-1.38 22 Nov 2005 10:50:55 -0000 1.1.2.14
-@@ -3,6 +3,20 @@
-
- General:
-
-+Changes to 1.38.2:
-+20Oct05
-+- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+ says this does not fix *his* bug).
-+- Fix cancel failure bug. Bug #481
-+- Fix failure when Pool name has spaces. Bug #487
-+- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+- Fix a couple of free()s in src/filed/acl.c
-+- Fix memory overrun in bfile.c in building OS X resource
-+ fork filename. Bug #489
-+- Add Pool name to SD status output.
-+- Add Python install dir for Solaris to configure. Bug #492
-+
- Changes to 1.38.1:
- 14Oct05
- - Apply SunOS patch for ACLs submitted by David Duchscher.
-Index: projects
-===================================================================
-RCS file: /cvsroot/bacula/bacula/projects,v
-retrieving revision 1.12.2.3
-retrieving revision 1.12.2.4
-diff -u -r1.12.2.3 -r1.12.2.4
---- projects 10 Nov 2005 20:25:27 -0000 1.12.2.3
-+++ projects 22 Nov 2005 10:50:55 -0000 1.12.2.4
-@@ -228,7 +228,175 @@
-
- Why: Performance enhancement.
-
-+Item 13: Let Bacula log tape usage and handle drive cleaning cycles.
-+ Date: November 11, 2005
-+ Origin: Arno Lehmann <al at its-lehmann dot de>
-+ Status:
-+
-+ What: Make Bacula manage tape life cycle information and drive
-+ cleaning cycles.
-+
-+ Why: Both parts of this project are important when operating backups.
-+ We need to know which tapes need replacement, and we need to
-+ make sure the drives are cleaned when necessary. While many
-+ tape libraries and even autoloaders can handle all this
-+ automatically, support by Bacula can be helpful for smaller
-+ (older) libraries and single drives. Also, checking drive
-+ status during operation can prevent some failures (as I had to
-+ learn the hard way...)
-+
-+ Notes: First, Bacula could (and even does, to some limited extent)
-+ record tape and drive usage. For tapes, the number of mounts,
-+ the amount of data, and the time the tape has actually been
-+ running could be recorded. Data fields for Read and Write time
-+ and Nmber of mounts already exist in the catalog (I'm not sure
-+ if VolBytes is the sum of all bytes ever written to that volume
-+ by Bacula). This information can be important when determining
-+ which media to replace. For the tape drives known to Bacula,
-+ similar information is interesting to determine the device
-+ status and expected life time: Time it's been Reading and
-+ Writing, number of tape Loads / Unloads / Errors. This
-+ information is not yet recorded as far as I know.
-+
-+ The next step would be implementing drive cleaning setup.
-+ Bacula already has knowledge about cleaning tapes. Once it has
-+ some information about cleaning cycles (measured in drive run
-+ time, number of tapes used, or calender days, for example) it
-+ can automatically execute tape cleaning (with an autochanger,
-+ obviously) or ask for operator assistence loading a cleaning
-+ tape.
-+
-+ The next step would be to implement TAPEALERT checks not only
-+ when changing tapes and only sending he information to the
-+ administrator, but rather checking after each tape error,
-+ checking on a regular basis (for example after each tape file),
-+ and also before unloading and after loading a new tape. Then,
-+ depending on the drives TAPEALERT state and the know drive
-+ cleaning state Bacula could automatically schedule later
-+ cleaning, clean immediately, or inform the operator.
-+
-+ Implementing this would perhaps require another catalog change
-+ and perhaps major changes in SD code and the DIR-SD protocoll,
-+ so I'd only consider this worth implementing if it would
-+ actually be used or even needed by many people.
-+
-+Item 14: Merging of multiple backups into a single one. (Also called Synthetic
-+ Backup or Consolidation).
-+
-+ Origin: Marc Cousin and Eric Bollengier
-+ Date: 15 November 2005
-+ Status: Depends on first implementing project Item 1 (Migration).
-+
-+ What: A merged backup is a backup made without connecting to the Client.
-+ It would be a Merge of existing backups into a single backup.
-+ In effect, it is like a restore but to the backup medium.
-+
-+ For instance, say that last sunday we made a full backup. Then
-+ all week long, we created incremental backups, in order to do
-+ them fast. Now comes sunday again, and we need another full.
-+ The merged backup makes it possible to do instead an incremental
-+ backup (during the night for instance), and then create a merged
-+ backup during the day, by using the full and incrementals from
-+ the week. The merged backup will be exactly like a full made
-+ sunday night on the tape, but the production interruption on the
-+ Client will be minimal, as the Client will only have to send
-+ incrementals.
-+
-+ In fact, if it's done correctly, you could merge all the
-+ Incrementals into single Incremental, or all the Incrementals
-+ and the last Differential into a new Differential, or the Full,
-+ last differential and all the Incrementals into a new Full
-+ backup. And there is no need to involve the Client.
-+
-+ Why: The benefit is that :
-+ - the Client just does an incremental ;
-+ - the merged backup on tape is just as a single full backup,
-+ and can be restored very fast.
-+
-+ This is also a way of reducing the backup data since the old
-+ data can then be pruned (or not) from the catalog, possibly
-+ allowing older volumes to be recycled
-+
-+Item 15: Automatic disabling of devices
-+ Date: 2005-11-11
-+ Origin: Peter Eriksson <peter at ifm.liu dot se>
-+ Status:
-+
-+ What: After a configurable amount of fatal errors with a tape drive
-+ Bacula should automatically disable further use of a certain
-+ tape drive. There should also be "disable"/"enable" commands in
-+ the "bconsole" tool.
-+
-+ Why: On a multi-drive jukebox there is a possibility of tape drives
-+ going bad during large backups (needing a cleaning tape run,
-+ tapes getting stuck). It would be advantageous if Bacula would
-+ automatically disable further use of a problematic tape drive
-+ after a configurable amount of errors has occured.
-+
-+ An example: I have a multi-drive jukebox (6 drives, 380+ slots)
-+ where tapes occasionally get stuck inside the drive. Bacula will
-+ notice that the "mtx-changer" command will fail and then fail
-+ any backup jobs trying to use that drive. However, it will still
-+ keep on trying to run new jobs using that drive and fail -
-+ forever, and thus failing lots and lots of jobs... Since we have
-+ many drives Bacula could have just automatically disabled
-+ further use of that drive and used one of the other ones
-+ instead.
-+
-+
-+Item 16: Directive/mode to backup only file changes, not entire file
-+ Date: 11 November 2005
-+ Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
-+ Marek Bajon <mbajon at bimsplus dot com dot pl>
-+ Status: RFC
-+
-+ What: Currently when a file changes, the entire file will be backed up in
-+ the next incremental or full backup. To save space on the tapes
-+ it would be nice to have a mode whereby only the changes to the
-+ file would be backed up when it is changed.
-+
-+ Why: This would save lots of space when backing up large files such as
-+ logs, mbox files, Outlook PST files and the like.
-+
-+ Notes: This would require the usage of disk-based volumes as comparing
-+ files would not be feasible using a tape drive.
-+
-+Item 17: Quick release of FD-SD connection
-+ Origin: Frank Volf (frank at deze dot org)
-+ Date: 17 november 2005
-+ Status:
-+
-+ What: In the bacula implementation a backup is finished after all data
-+ and attributes are succesfully written to storage. When using a
-+ tape backup it is very annoying that a backup can take a day,
-+ simply because the current tape (or whatever) is full and the
-+ administrator has not put a new one in. During that time the
-+ system cannot be taken off-line, because there is still an open
-+ session between the storage daemon and the file daemon on the
-+ client.
-+
-+ Although this is a very good strategey for making "safe backups"
-+ This can be annoying for e.g. laptops, that must remain
-+ connected until the bacukp is completed.
-+
-+ Using a new feature called "migration" it will be possible to
-+ spool first to harddisk (using a special 'spool' migration
-+ scheme) and then migrate the backup to tape.
-+
-+ There is still the problem of getting the attributes committed.
-+ If it takes a very long time to do, with the current code, the
-+ job has not terminated, and the File daemon is not freed up. The
-+ Storage daemon should release the File daemon as soon as all the
-+ file data and all the attributes have been sent to it (the SD).
-+ Currently the SD waits until everything is on tape and all the
-+ attributes are transmitted to the Director before signalling
-+ completion to the FD. I don't think I would have any problem
-+ changing this. The reason is that even if the FD reports back to
-+ the Dir that all is OK, the job will not terminate until the SD
-+ has done the same thing -- so in a way keeping the SD-FD link
-+ open to the very end is not really very productive ...
-
-+ Why: Makes backup of laptops much easier.
-
-
- ============= Empty RFC form ===========
-@@ -245,33 +413,4 @@
- ============== End RFC form ==============
-
-
--Items completed for release 1.38.0:
--#4 Embedded Python Scripting (implemented in all Daemons)
--#5 Events that call a Python program (Implemented in all
-- daemons, but more cleanup work to be done).
--#6 Select one from among Multiple Storage Devices for Job.
-- This is already implemented in 1.37.
--#7 Single Job Writing to Multiple Storage Devices. This is
-- currently implemented with a Clone feature.
--#- Full multiple drive Autochanger support (done in 1.37)
--#- Built in support for communications encryption (TLS)
-- done by Landon Fuller.
--# Support for Unicode characters
-- (via UTF-8) on Win32 machines thanks to Thorsten Engel.
--Item 8: Break the one-to-one Relationship between a Job and a
-- Specific Storage Device (or Devices if #10 is implemented).
--
--Completed items from last year's list:
--Item 1: Multiple simultaneous Jobs. (done)
--Item 3: Write the bscan program -- also write a bcopy program (done).
--Item 5: Implement Label templates (done).
--Item 6: Write a regression script (done)
--Item 9: Add SSL to daemon communications (done by Landon Fuller)
--Item 10: Define definitive tape format (done)
--Item 3: GUI for interactive restore. Partially Implemented in 1.34
-- Note, there is now a complete Webmin plugin, a partial
-- GNOME console, and an excellent wx-console GUI.
--Item 4: GUI for interactive backup
--Item 2: Job Data Spooling.
-- Done: Regular expression matching.
--Item 10: New daemon communication protocol (this has been dropped).
-+Items completed for release 1.38.0 -- see kernsdone
-Index: autoconf/configure.in
-===================================================================
-RCS file: /cvsroot/bacula/bacula/autoconf/configure.in,v
-retrieving revision 1.184.2.4
-retrieving revision 1.184.2.5
-diff -u -r1.184.2.4 -r1.184.2.5
---- autoconf/configure.in 13 Nov 2005 10:51:17 -0000 1.184.2.4
-+++ autoconf/configure.in 22 Nov 2005 10:50:55 -0000 1.184.2.5
-@@ -604,7 +604,7 @@
- PYTHON_LIBS=
- if test "$withval" != "no"; then
- if test "$withval" = "yes"; then
-- for python_root in /usr /usr/local; do
-+ for python_root in /usr /usr/local /usr/sfw; do
- if test -f $python_root/include/python2.2/Python.h; then
- PYTHON_INCDIR=-I$python_root/include/python2.2
- PYTHON_LIBS="-L$python_root/lib/python2.2/config -lpython2.2"
-Index: patches/1.38.1-to-1.38.2.patch
-===================================================================
-RCS file: patches/1.38.1-to-1.38.2.patch
-diff -N patches/1.38.1-to-1.38.2.patch
---- /dev/null 1 Jan 1970 00:00:00 -0000
-+++ patches/1.38.1-to-1.38.2.patch 22 Nov 2005 10:52:49 -0000 1.1.2.3
-@@ -0,0 +1,6901 @@
-+
-+ This patch fixes the following bugs:
-+
-+- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+ says that this patch does not fix his problem)
-+- Fix cancel failure bug. Bug #481
-+- Fix failure when Pool name has spaces. Bug #487
-+- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+- Fix a couple of free()s in src/filed/acl.c
-+- Fix memory overrun in bfile.c in building OS X resource
-+ fork filename. Bug #489
-+- Add Pool name to SD status output.
-+- Add Python install dir for Solaris to configure. Bug #492
-+
-+This patch is applied to Bacula source version 1.38.1 and will
-+produce Bacula source version 1.38.2. Apply it with:
-+
-+ cd <bacula-1.38.1-source>
-+ ./configure (your options) if not already done
-+ patch -p0 <1.38.1-to-1.38.2.patch
-+ make
-+ make install
-+
-+Index: ChangeLog
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/ChangeLog,v
-+retrieving revision 1.154.2.7
-+retrieving revision 1.154.2.8
-+diff -u -r1.154.2.7 -r1.154.2.8
-+--- ChangeLog 15 Nov 2005 09:27:19 -0000 1.154.2.7
-++++ ChangeLog 22 Nov 2005 10:50:54 -0000 1.154.2.8
-+@@ -1,4 +1,15 @@
-+
-++Changes to 1.38.2:
-++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++- Fix bnet-server bug found on OpenBSD. Bug #486
-++- Fix cancel failure bug. Bug #481
-++- Fix failure when Pool name has spaces. Bug #487
-++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++- Fix a couple of free()s in src/filed/acl.c
-++- Fix memory overrun in bfile.c in building OS X resource
-++ fork filename. Bug #489
-++- Add Pool name to SD status output.
-++- Add Python install dir for Solaris to configure. Bug #492
-+
-+ Changes to 1.38.1:
-+ - Apply SunOS patch for ACLs submitted by David Duchscher.
-+Index: ReleaseNotes
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/ReleaseNotes,v
-+retrieving revision 1.147.2.9
-+retrieving revision 1.147.2.10
-+diff -u -r1.147.2.9 -r1.147.2.10
-+--- ReleaseNotes 15 Nov 2005 09:27:19 -0000 1.147.2.9
-++++ ReleaseNotes 22 Nov 2005 10:50:54 -0000 1.147.2.10
-+@@ -1,10 +1,22 @@
-+
-+- Release Notes for Bacula 1.38.1
-++ Release Notes for Bacula 1.38.2
-+
-+ Bacula code: Total files = 420 Total lines = 138,440 (*.h *.c *.in)
-+ 20,440 additional lines of code since version 1.36.3
-+
-+-Changes since 1.38.0:
-++Changes to 1.38.2:
-++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++- Fix bnet-server bug found on OpenBSD. Bug #486
-++- Fix cancel failure bug. Bug #481
-++- Fix failure when Pool name has spaces. Bug #487
-++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++- Fix a couple of free()s in src/filed/acl.c
-++- Fix memory overrun in bfile.c in building OS X resource
-++ fork filename. Bug #489
-++- Add Pool name to SD status output.
-++- Add Python install dir for Solaris to configure. Bug #492
-++
-++Changes to 1.38.1:
-+ - Corrected ACL for Solaris (David Duchscher and Attila Fulop).
-+ - Add bacula_mail_summary.sh to examples directory. It makes
-+ a single email summary of any number of jobs. Submitted
-+Index: configure
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/configure,v
-+retrieving revision 1.203.2.5
-+retrieving revision 1.203.2.6
-+diff -u -r1.203.2.5 -r1.203.2.6
-+--- configure 13 Nov 2005 10:51:17 -0000 1.203.2.5
-++++ configure 22 Nov 2005 10:50:54 -0000 1.203.2.6
-+@@ -14948,7 +14948,7 @@
-+ PYTHON_LIBS=
-+ if test "$withval" != "no"; then
-+ if test "$withval" = "yes"; then
-+- for python_root in /usr /usr/local; do
-++ for python_root in /usr /usr/local /usr/sfw; do
-+ if test -f $python_root/include/python2.2/Python.h; then
-+ PYTHON_INCDIR=-I$python_root/include/python2.2
-+ PYTHON_LIBS="-L$python_root/lib/python2.2/config -lpython2.2"
-+Index: kernstodo
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/kernstodo,v
-+retrieving revision 1.570.2.6
-+retrieving revision 1.570.2.7
-+diff -u -r1.570.2.6 -r1.570.2.7
-+--- kernstodo 4 Nov 2005 09:16:49 -0000 1.570.2.6
-++++ kernstodo 22 Nov 2005 10:50:55 -0000 1.570.2.7
-+@@ -1,5 +1,5 @@
-+ Kern's ToDo List
-+- 03 November 2005
-++ 21 November 2005
-+
-+ Major development:
-+ Project Developer
-+@@ -7,8 +7,6 @@
-+ Version 1.37 Kern (see below)
-+ ========================================================
-+
-+-Final items for 1.37 before release:
-+-
-+ Document:
-+ - Does ClientRunAfterJob fail the job on a bad return code?
-+ - Document cleaning up the spool files:
-+@@ -18,6 +16,8 @@
-+ - Does WildFile match against full name? Doc.
-+
-+ For 1.39:
-++- Make sure that all do_prompt() calls in Dir check for
-++ -1 (error) and -2 (cancel) returns.
-+ - Look at -D_FORTIFY_SOURCE=2
-+ - Add Win32 FileSet definition somewhere
-+ - Look at fixing restore status stats in SD.
-+@@ -27,6 +27,12 @@
-+ encountered, read many times (as it currently does), and if the
-+ block cannot be read, skip to the next block, and try again. If
-+ that fails, skip to the next file and try again, ...
-++- Add level table:
-++ create table LevelType (LevelType binary(1), LevelTypeLong tinyblob);
-++ insert into LevelType (LevelType,LevelTypeLong) values
-++ ("F","Full"),
-++ ("D","Diff"),
-++ ("I","Inc");
-+ - Add ACL to restore only to original location.
-+ - Add a recursive mark command (rmark) to restore.
-+ - "Minimum Job Interval = nnn" sets minimum interval between Jobs
-+@@ -1246,219 +1252,4 @@
-+ ====
-+
-+
-+-=== Done
-+-- Save mount point for directories not traversed with onefs=yes.
-+-- Add seconds to start and end times in the Job report output.
-+-- if 2 concurrent backups are attempted on the same tape
-+- drive (autoloader) into different tape pools, one of them will exit
-+- fatally instead of halting until the drive is idle
-+-- Update StartTime if job held in Job Queue.
-+-- Look at www.nu2.nu/pebuilder as a helper for full windows
-+- bare metal restore. (done by Scott)
-+-- Fix orphanned buffers:
-+- Orphaned buffer: 24 bytes allocated at line 808 of rufus-dir job.c
-+- Orphaned buffer: 40 bytes allocated at line 45 of rufus-dir alist.c
-+-- Implement Preben's suggestion to add
-+- File System Types = ext2, ext3
-+- to FileSets, thus simplifying backup of *all* local partitions.
-+-- Try to open a device on each Job if it was not opened
-+- when the SD started.
-+-- Add dump of VolSessionId/Time and FileIndex with bls.
-+-- If Bacula does not find the right tape in the Autochanger,
-+- then mark the tape in error and move on rather than asking
-+- for operator intervention.
-+-- Cancel command should include JobId in list of Jobs.
-+-- Add performance testing hooks
-+-- Bootstrap from JobMedia records.
-+-- Implement WildFile and WildDir to solve problem of
-+- saving only *.doc files.
-+-- Fix
-+- Please use the "label" command to create a new Volume for:
-+- Storage: DDS-4-changer
-+- Media type:
-+- Pool: Default
-+- label
-+- The defined Storage resources are:
-+-- Copy Changer Device and Changer Command from Autochanger
-+- to Device resource in SD if none given in Device resource.
-+-- 1. Automatic use of more than one drive in an autochanger (done)
-+-- 2. Automatic selection of the correct drive for each Job (i.e.
-+- selects a drive with an appropriate Volume for the Job) (done)
-+-- 6. Allow multiple simultaneous Jobs referencing the same pool write
-+- to several tapes (some new directive(s) are are probably needed for
-+- this) (done)
-+-- Locking (done)
-+-- Key on Storage rather than Pool (done)
-+-- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
-+-- Synchronize multiple drives so that not more
-+- than one loads a tape and any time (done)
-+-- 4. Use Changer Device and Changer Command specified in the
-+- Autochanger resource, if none is found in the Device resource.
-+- You can continue to specify them in the Device resource if you want
-+- or need them to be different for each device.
-+-- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
-+- that can allow a Device be part of an Autochanger, and hence the changer
-+- script protected, but if set to no, will prevent the Device from being
-+- automatically selected from the changer. This allows the device to
-+- be directly accessed through its Device name, but not through the
-+- AutoChanger name.
-+-#6 Select one from among Multiple Storage Devices for Job
-+-#5 Events that call a Python program
-+- (Implemented in Dir/SD)
-+-- Make sure the Device name is in the Query packet returned.
-+-- Don't start a second file job if one is already running.
-+-- Implement EOF/EOV labels for ANSI labels
-+-- Implement IBM labels.
-+-- When Python creates a new label, the tape is immediately
-+- recycled and no label created. This happens when using
-+- autolabeling -- even when Python doesn't generate the name.
-+-- Scratch Pool where the volumes can be re-assigned to any Pool.
-+-- 28-Mar 23:19 rufus-sd: acquire.c:379 Device "DDS-4" (/dev/nst0)
-+- is busy reading. Job 6 canceled.
-+-- Remove separate thread for opening devices in SD. On the other
-+- hand, don't block waiting for open() for devices.
-+-- Fix code to either handle updating NumVol or to calculate it in
-+- Dir next_vol.c
-+-- Ensure that you cannot exclude a directory or a file explicitly
-+- Included with File.
-+-#4 Embedded Python Scripting
-+- (Implemented in Dir/SD/FD)
-+-- Add Python writable variable for changing the Priority,
-+- Client, Storage, JobStatus (error), ...
-+-- SD Python
-+- - Solicit Events
-+-- Add disk seeking on restore; turn off seek on tapes.
-+- stored/match_bsr.c
-+-- Look at dird_conf.c:1000: warning: `int size'
-+- might be used uninitialized in this function
-+-- Indicate when a Job is purged/pruned during restore.
-+-- Implement some way to turn off automatic pruning in Jobs.
-+-- Implement a way an Admin Job can prune, possibly multiple
-+- clients -- Python script?
-+-- Look at Preben's acl.c error handling code.
-+-- SD crashes after a tape restore then doing a backup.
-+-- If drive is opened read/write, close it and re-open
-+- read-only if doing a restore, and vice-versa.
-+-- Windows restore:
-+- data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
-+- > ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
-+- > Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen
-+- > Prozess verwendet wird.
-+- Restore restores all files, but then fails at the end trying
-+- to set the attributes of e:
-+- from failed jobs.- Resolve the problem between Device name and Archive name,
-+- and fix SD messages.
-+-- Tell the "restore" user when browsing is no longer possible.
-+-- Add a restore directory-x
-+-- Write non-optimized bsrs from the JobMedia and Media records,
-+- even after Files are pruned.
-+-- Delete Stripe and Copy from VolParams to save space.
-+-- Fix option 2 of restore -- list where file is backed up -- require Client,
-+- then list last 20 backups.
-+-- Finish implementation of passing all Storage and Device needs to
-+- the SD.
-+-- Move test for max wait time exceeded in job.c up -- Peter's idea.
-+-## Consider moving docs to their own project.
-+-## Move rescue to its own project.
-+-- Add client version to the Client name line that prints in
-+- the Job report.
-+-- Fix the Rescue CDROM.
-+-- By the way: on page http://www.bacula.org/?page=tapedrives , at the
-+- bottom, the link to "Tape Testing Chapter" is broken. It goes to
-+- /html-manual/... while the others point to /rel-manual/...
-+-- Device resource needs the "name" of the SD.
-+-- Specify a single directory to restore.
-+-- Implement MediaType keyword in bsr?
-+-- Add a date and time stamp at the beginning of every line in the
-+- Job report (Volker Sauer).
-+-- Add level to estimate command.
-+-- Add "limit=n" for "list jobs"
-+-- Make bootstrap filename unique.
-+-- Make Dmsg look at global before calling subroutine.
-+-- From Chris Hull:
-+- it seems to be complaining about 12:00pm which should be a valid 12
-+- hour time. I changed the time to 11:59am and everything works fine.
-+- Also 12:00am works fine. 0:00pm also works (which I don't think
-+- should). None of the values 12:00pm - 12:59pm work for that matter.
-+-- Require restore via the restore command or make a restore Job
-+- get the bootstrap file.
-+-- Implement Maximum Job Spool Size
-+-- Fix 3993 error in SD. It forgets to look at autochanger
-+- resource for device command, ...
-+-- 3. Prevent two drives requesting the same Volume in any given
-+- autochanger, by checking if a Volume is mounted on another drive
-+- in an Autochanger.
-+-- Upgrade to MySQL 4.1.12 See:
-+- http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
-+-- Add # Job Level date to bsr file
-+-- Implement "PreferMountedVolumes = yes|no" in Job resource.
-+-## Integrate web-bacula into a new Bacula project with
-+- bimagemgr.
-+-- Cleaning tapes should have Status "Cleaning" rather than append.
-+-- Make sure that Python has access to Client address/port so that
-+- it can check if Clients are alive.
-+-- Review all items in "restore".
-+-- Fix PostgreSQL GROUP BY problems in restore.
-+-- Fix PostgreSQL sql problems in bugs.
-+-- After rename
-+- 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume
-+- "DLT-13Feb04".
-+- Current Volume "DLT-04Jul05" not acceptable because:
-+- 1997 Volume "DLT-13Feb04" not in catalog.
-+- 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device
-+- "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
-+-## Create a new GUI chapter explaining all the GUI programs.
-+-- Make "update slots" when pointing to Autochanger, remove
-+- all Volumes from other drives. "update slots all-drives"?
-+- No, this is done by modifying mtx-changer to list what is
-+- in the drives.
-+-- Finish TLS implementation.
-+-- Port limiting -m in iptables to prevent DoS attacks
-+- could cause broken pipes on Bacula.
-+-6. Build and test the Volume Shadow Copy (VSS) for Win32.
-+-- Allow cancel of unknown Job
-+-- State not saved when closing Win32 FD by icon
-+-- bsr-opt-test fails. bsr deleted. Fix.
-+-- Move Python daemon variables from Job to Bacula object.
-+- WorkingDir, ConfigFile
-+-- Document that Bootstrap files can be written with cataloging
-+- turned off.
-+-- Document details of ANSI/IBM labels
-+-- OS linux 2.4
-+- 1) ADIC, DLT, FastStor 4000, 7*20GB
-+-- Linux Sony LIB-D81, AIT-3 library works.
-+-- Doc the following
-+- to activate, check or disable the hardware compression feature on my
-+- exb-8900 i use the exabyte "MammothTool" you can get it here:
-+- http://www.exabyte.com/support/online/downloads/index.cfm
-+- There is a solaris version of this tool. With option -C 0 or 1 you can
-+- disable or activate compression. Start this tool without any options for
-+- a small reference.
-+-- Document Heartbeat Interval in the dealing with firewalls section.
-+-- Document new CDROM directory.
-+-- On Win32 working directory must have drive letter ????
-+-- On Win32 working directory must be writable by SYSTEM to
-+- do restores.
-+-- Document that ChangerDevice is used for Alert command.
-+-- Add better documentation on how restores can be done
-+-8. Take one more try at making DVD writing work (no go)
-+-7. Write a bacula-web document
-+-- Why isn't the DEVICE structure defined when doing
-+- a reservation?
-+-- Multi-drive changer seems to only use drive 0
-+- Multiple drives don't seem to be opened.
-+-- My database is growing
-+-- Call GetLastError() in the berrno constructor rather
-+- than delaying until strerror.
-+-- Tape xxx in drive 0, requested in drive 1
-+-- The mount command does not work with drives other than 0.
-+-- A mount should cause the SD to re-examine what Slot is
-+- loaded.
-+-- The SD locks on to the first available drive then
-+- wants a Volume that is released but in another drive --
-+- chaos.
-+-- Run the regression scripts on Solaris and FreeBSD
-+-- Figure out how to package gui, and rescue programs.
-+-- Add a .dir command to restore tree code to eliminate the problem
-+-- Mount after manually unloading changer causes hang in SD
-+-- Fix JobACL with restore by JobId.
-++=== Done -- see kernsdone
-+Index: kes-1.38
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-+retrieving revision 1.1.2.13
-+retrieving revision 1.1.2.14
-+diff -u -r1.1.2.13 -r1.1.2.14
-+--- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-++++ kes-1.38 22 Nov 2005 10:50:55 -0000 1.1.2.14
-+@@ -3,6 +3,20 @@
-+
-+ General:
-+
-++Changes to 1.38.2:
-++20Oct05
-++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++ says this does not fix *his* bug).
-++- Fix cancel failure bug. Bug #481
-++- Fix failure when Pool name has spaces. Bug #487
-++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++- Fix a couple of free()s in src/filed/acl.c
-++- Fix memory overrun in bfile.c in building OS X resource
-++ fork filename. Bug #489
-++- Add Pool name to SD status output.
-++- Add Python install dir for Solaris to configure. Bug #492
-++
-+ Changes to 1.38.1:
-+ 14Oct05
-+ - Apply SunOS patch for ACLs submitted by David Duchscher.
-+Index: projects
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/projects,v
-+retrieving revision 1.12.2.3
-+retrieving revision 1.12.2.4
-+diff -u -r1.12.2.3 -r1.12.2.4
-+--- projects 10 Nov 2005 20:25:27 -0000 1.12.2.3
-++++ projects 22 Nov 2005 10:50:55 -0000 1.12.2.4
-+@@ -228,7 +228,175 @@
-+
-+ Why: Performance enhancement.
-+
-++Item 13: Let Bacula log tape usage and handle drive cleaning cycles.
-++ Date: November 11, 2005
-++ Origin: Arno Lehmann <al at its-lehmann dot de>
-++ Status:
-++
-++ What: Make Bacula manage tape life cycle information and drive
-++ cleaning cycles.
-++
-++ Why: Both parts of this project are important when operating backups.
-++ We need to know which tapes need replacement, and we need to
-++ make sure the drives are cleaned when necessary. While many
-++ tape libraries and even autoloaders can handle all this
-++ automatically, support by Bacula can be helpful for smaller
-++ (older) libraries and single drives. Also, checking drive
-++ status during operation can prevent some failures (as I had to
-++ learn the hard way...)
-++
-++ Notes: First, Bacula could (and even does, to some limited extent)
-++ record tape and drive usage. For tapes, the number of mounts,
-++ the amount of data, and the time the tape has actually been
-++ running could be recorded. Data fields for Read and Write time
-++ and Nmber of mounts already exist in the catalog (I'm not sure
-++ if VolBytes is the sum of all bytes ever written to that volume
-++ by Bacula). This information can be important when determining
-++ which media to replace. For the tape drives known to Bacula,
-++ similar information is interesting to determine the device
-++ status and expected life time: Time it's been Reading and
-++ Writing, number of tape Loads / Unloads / Errors. This
-++ information is not yet recorded as far as I know.
-++
-++ The next step would be implementing drive cleaning setup.
-++ Bacula already has knowledge about cleaning tapes. Once it has
-++ some information about cleaning cycles (measured in drive run
-++ time, number of tapes used, or calender days, for example) it
-++ can automatically execute tape cleaning (with an autochanger,
-++ obviously) or ask for operator assistence loading a cleaning
-++ tape.
-++
-++ The next step would be to implement TAPEALERT checks not only
-++ when changing tapes and only sending he information to the
-++ administrator, but rather checking after each tape error,
-++ checking on a regular basis (for example after each tape file),
-++ and also before unloading and after loading a new tape. Then,
-++ depending on the drives TAPEALERT state and the know drive
-++ cleaning state Bacula could automatically schedule later
-++ cleaning, clean immediately, or inform the operator.
-++
-++ Implementing this would perhaps require another catalog change
-++ and perhaps major changes in SD code and the DIR-SD protocoll,
-++ so I'd only consider this worth implementing if it would
-++ actually be used or even needed by many people.
-++
-++Item 14: Merging of multiple backups into a single one. (Also called Synthetic
-++ Backup or Consolidation).
-++
-++ Origin: Marc Cousin and Eric Bollengier
-++ Date: 15 November 2005
-++ Status: Depends on first implementing project Item 1 (Migration).
-++
-++ What: A merged backup is a backup made without connecting to the Client.
-++ It would be a Merge of existing backups into a single backup.
-++ In effect, it is like a restore but to the backup medium.
-++
-++ For instance, say that last sunday we made a full backup. Then
-++ all week long, we created incremental backups, in order to do
-++ them fast. Now comes sunday again, and we need another full.
-++ The merged backup makes it possible to do instead an incremental
-++ backup (during the night for instance), and then create a merged
-++ backup during the day, by using the full and incrementals from
-++ the week. The merged backup will be exactly like a full made
-++ sunday night on the tape, but the production interruption on the
-++ Client will be minimal, as the Client will only have to send
-++ incrementals.
-++
-++ In fact, if it's done correctly, you could merge all the
-++ Incrementals into single Incremental, or all the Incrementals
-++ and the last Differential into a new Differential, or the Full,
-++ last differential and all the Incrementals into a new Full
-++ backup. And there is no need to involve the Client.
-++
-++ Why: The benefit is that :
-++ - the Client just does an incremental ;
-++ - the merged backup on tape is just as a single full backup,
-++ and can be restored very fast.
-++
-++ This is also a way of reducing the backup data since the old
-++ data can then be pruned (or not) from the catalog, possibly
-++ allowing older volumes to be recycled
-++
-++Item 15: Automatic disabling of devices
-++ Date: 2005-11-11
-++ Origin: Peter Eriksson <peter at ifm.liu dot se>
-++ Status:
-++
-++ What: After a configurable amount of fatal errors with a tape drive
-++ Bacula should automatically disable further use of a certain
-++ tape drive. There should also be "disable"/"enable" commands in
-++ the "bconsole" tool.
-++
-++ Why: On a multi-drive jukebox there is a possibility of tape drives
-++ going bad during large backups (needing a cleaning tape run,
-++ tapes getting stuck). It would be advantageous if Bacula would
-++ automatically disable further use of a problematic tape drive
-++ after a configurable amount of errors has occured.
-++
-++ An example: I have a multi-drive jukebox (6 drives, 380+ slots)
-++ where tapes occasionally get stuck inside the drive. Bacula will
-++ notice that the "mtx-changer" command will fail and then fail
-++ any backup jobs trying to use that drive. However, it will still
-++ keep on trying to run new jobs using that drive and fail -
-++ forever, and thus failing lots and lots of jobs... Since we have
-++ many drives Bacula could have just automatically disabled
-++ further use of that drive and used one of the other ones
-++ instead.
-++
-++
-++Item 16: Directive/mode to backup only file changes, not entire file
-++ Date: 11 November 2005
-++ Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
-++ Marek Bajon <mbajon at bimsplus dot com dot pl>
-++ Status: RFC
-++
-++ What: Currently when a file changes, the entire file will be backed up in
-++ the next incremental or full backup. To save space on the tapes
-++ it would be nice to have a mode whereby only the changes to the
-++ file would be backed up when it is changed.
-++
-++ Why: This would save lots of space when backing up large files such as
-++ logs, mbox files, Outlook PST files and the like.
-++
-++ Notes: This would require the usage of disk-based volumes as comparing
-++ files would not be feasible using a tape drive.
-++
-++Item 17: Quick release of FD-SD connection
-++ Origin: Frank Volf (frank at deze dot org)
-++ Date: 17 november 2005
-++ Status:
-++
-++ What: In the bacula implementation a backup is finished after all data
-++ and attributes are succesfully written to storage. When using a
-++ tape backup it is very annoying that a backup can take a day,
-++ simply because the current tape (or whatever) is full and the
-++ administrator has not put a new one in. During that time the
-++ system cannot be taken off-line, because there is still an open
-++ session between the storage daemon and the file daemon on the
-++ client.
-++
-++ Although this is a very good strategey for making "safe backups"
-++ This can be annoying for e.g. laptops, that must remain
-++ connected until the bacukp is completed.
-++
-++ Using a new feature called "migration" it will be possible to
-++ spool first to harddisk (using a special 'spool' migration
-++ scheme) and then migrate the backup to tape.
-++
-++ There is still the problem of getting the attributes committed.
-++ If it takes a very long time to do, with the current code, the
-++ job has not terminated, and the File daemon is not freed up. The
-++ Storage daemon should release the File daemon as soon as all the
-++ file data and all the attributes have been sent to it (the SD).
-++ Currently the SD waits until everything is on tape and all the
-++ attributes are transmitted to the Director before signalling
-++ completion to the FD. I don't think I would have any problem
-++ changing this. The reason is that even if the FD reports back to
-++ the Dir that all is OK, the job will not terminate until the SD
-++ has done the same thing -- so in a way keeping the SD-FD link
-++ open to the very end is not really very productive ...
-+
-++ Why: Makes backup of laptops much easier.
-+
-+
-+ ============= Empty RFC form ===========
-+@@ -245,33 +413,4 @@
-+ ============== End RFC form ==============
-+
-+
-+-Items completed for release 1.38.0:
-+-#4 Embedded Python Scripting (implemented in all Daemons)
-+-#5 Events that call a Python program (Implemented in all
-+- daemons, but more cleanup work to be done).
-+-#6 Select one from among Multiple Storage Devices for Job.
-+- This is already implemented in 1.37.
-+-#7 Single Job Writing to Multiple Storage Devices. This is
-+- currently implemented with a Clone feature.
-+-#- Full multiple drive Autochanger support (done in 1.37)
-+-#- Built in support for communications encryption (TLS)
-+- done by Landon Fuller.
-+-# Support for Unicode characters
-+- (via UTF-8) on Win32 machines thanks to Thorsten Engel.
-+-Item 8: Break the one-to-one Relationship between a Job and a
-+- Specific Storage Device (or Devices if #10 is implemented).
-+-
-+-Completed items from last year's list:
-+-Item 1: Multiple simultaneous Jobs. (done)
-+-Item 3: Write the bscan program -- also write a bcopy program (done).
-+-Item 5: Implement Label templates (done).
-+-Item 6: Write a regression script (done)
-+-Item 9: Add SSL to daemon communications (done by Landon Fuller)
-+-Item 10: Define definitive tape format (done)
-+-Item 3: GUI for interactive restore. Partially Implemented in 1.34
-+- Note, there is now a complete Webmin plugin, a partial
-+- GNOME console, and an excellent wx-console GUI.
-+-Item 4: GUI for interactive backup
-+-Item 2: Job Data Spooling.
-+- Done: Regular expression matching.
-+-Item 10: New daemon communication protocol (this has been dropped).
-++Items completed for release 1.38.0 -- see kernsdone
-+Index: autoconf/configure.in
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/autoconf/configure.in,v
-+retrieving revision 1.184.2.4
-+retrieving revision 1.184.2.5
-+diff -u -r1.184.2.4 -r1.184.2.5
-+--- autoconf/configure.in 13 Nov 2005 10:51:17 -0000 1.184.2.4
-++++ autoconf/configure.in 22 Nov 2005 10:50:55 -0000 1.184.2.5
-+@@ -604,7 +604,7 @@
-+ PYTHON_LIBS=
-+ if test "$withval" != "no"; then
-+ if test "$withval" = "yes"; then
-+- for python_root in /usr /usr/local; do
-++ for python_root in /usr /usr/local /usr/sfw; do
-+ if test -f $python_root/include/python2.2/Python.h; then
-+ PYTHON_INCDIR=-I$python_root/include/python2.2
-+ PYTHON_LIBS="-L$python_root/lib/python2.2/config -lpython2.2"
-+Index: patches/1.38.1-to-1.38.2.patch
-+===================================================================
-+RCS file: patches/1.38.1-to-1.38.2.patch
-+diff -N patches/1.38.1-to-1.38.2.patch
-+--- /dev/null 1 Jan 1970 00:00:00 -0000
-++++ patches/1.38.1-to-1.38.2.patch 22 Nov 2005 10:50:55 -0000 1.1.2.2
-+@@ -0,0 +1,5704 @@
-++
-++ This patch fixes the following bugs:
-++
-++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++ says that this patch does not fix his problem)
-++- Fix cancel failure bug. Bug #481
-++- Fix failure when Pool name has spaces. Bug #487
-++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++- Fix a couple of free()s in src/filed/acl.c
-++- Fix memory overrun in bfile.c in building OS X resource
-++ fork filename. Bug #489
-++- Add Pool name to SD status output.
-++- Add Python install dir for Solaris to configure. Bug #492
-++
-++This patch is applied to Bacula source version 1.38.1 and will
-++produce Bacula source version 1.38.2. Apply it with:
-++
-++ cd <bacula-1.38.1-source>
-++ ./configure (your options) if not already done
-++ patch -p0 <1.38.1-to-1.38.2.patch
-++ make
-++ make install
-++
-++? osx_finder.patch
-++Index: ChangeLog
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/ChangeLog,v
-++retrieving revision 1.154.2.7
-++diff -u -r1.154.2.7 ChangeLog
-++--- ChangeLog 15 Nov 2005 09:27:19 -0000 1.154.2.7
-+++++ ChangeLog 22 Nov 2005 10:42:14 -0000
-++@@ -1,4 +1,14 @@
-++
-+++Changes to 1.38.2:
-+++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++- Fix bnet-server bug found on OpenBSD. Bug #486
-+++- Fix cancel failure bug. Bug #481
-+++- Fix failure when Pool name has spaces. Bug #487
-+++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++- Fix a couple of free()s in src/filed/acl.c
-+++- Fix memory overrun in bfile.c in building OS X resource
-+++ fork filename. Bug #489
-+++- Add Pool name to SD status output.
-++
-++ Changes to 1.38.1:
-++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-++Index: ReleaseNotes
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/ReleaseNotes,v
-++retrieving revision 1.147.2.9
-++diff -u -r1.147.2.9 ReleaseNotes
-++--- ReleaseNotes 15 Nov 2005 09:27:19 -0000 1.147.2.9
-+++++ ReleaseNotes 22 Nov 2005 10:42:15 -0000
-++@@ -1,10 +1,21 @@
-++
-++- Release Notes for Bacula 1.38.1
-+++ Release Notes for Bacula 1.38.2
-++
-++ Bacula code: Total files = 420 Total lines = 138,440 (*.h *.c *.in)
-++ 20,440 additional lines of code since version 1.36.3
-++
-++-Changes since 1.38.0:
-+++Changes to 1.38.2:
-+++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++- Fix bnet-server bug found on OpenBSD. Bug #486
-+++- Fix cancel failure bug. Bug #481
-+++- Fix failure when Pool name has spaces. Bug #487
-+++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++- Fix a couple of free()s in src/filed/acl.c
-+++- Fix memory overrun in bfile.c in building OS X resource
-+++ fork filename. Bug #489
-+++- Add Pool name to SD status output.
-+++
-+++Changes to 1.38.1:
-++ - Corrected ACL for Solaris (David Duchscher and Attila Fulop).
-++ - Add bacula_mail_summary.sh to examples directory. It makes
-++ a single email summary of any number of jobs. Submitted
-++Index: configure
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/configure,v
-++retrieving revision 1.203.2.5
-++diff -u -r1.203.2.5 configure
-++--- configure 13 Nov 2005 10:51:17 -0000 1.203.2.5
-+++++ configure 22 Nov 2005 10:42:19 -0000
-++@@ -14948,7 +14948,7 @@
-++ PYTHON_LIBS=
-++ if test "$withval" != "no"; then
-++ if test "$withval" = "yes"; then
-++- for python_root in /usr /usr/local; do
-+++ for python_root in /usr /usr/local /usr/sfw; do
-++ if test -f $python_root/include/python2.2/Python.h; then
-++ PYTHON_INCDIR=-I$python_root/include/python2.2
-++ PYTHON_LIBS="-L$python_root/lib/python2.2/config -lpython2.2"
-++Index: kernstodo
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/kernstodo,v
-++retrieving revision 1.570.2.6
-++diff -u -r1.570.2.6 kernstodo
-++--- kernstodo 4 Nov 2005 09:16:49 -0000 1.570.2.6
-+++++ kernstodo 22 Nov 2005 10:42:20 -0000
-++@@ -1,5 +1,5 @@
-++ Kern's ToDo List
-++- 03 November 2005
-+++ 21 November 2005
-++
-++ Major development:
-++ Project Developer
-++@@ -7,8 +7,6 @@
-++ Version 1.37 Kern (see below)
-++ ========================================================
-++
-++-Final items for 1.37 before release:
-++-
-++ Document:
-++ - Does ClientRunAfterJob fail the job on a bad return code?
-++ - Document cleaning up the spool files:
-++@@ -18,6 +16,8 @@
-++ - Does WildFile match against full name? Doc.
-++
-++ For 1.39:
-+++- Make sure that all do_prompt() calls in Dir check for
-+++ -1 (error) and -2 (cancel) returns.
-++ - Look at -D_FORTIFY_SOURCE=2
-++ - Add Win32 FileSet definition somewhere
-++ - Look at fixing restore status stats in SD.
-++@@ -27,6 +27,12 @@
-++ encountered, read many times (as it currently does), and if the
-++ block cannot be read, skip to the next block, and try again. If
-++ that fails, skip to the next file and try again, ...
-+++- Add level table:
-+++ create table LevelType (LevelType binary(1), LevelTypeLong tinyblob);
-+++ insert into LevelType (LevelType,LevelTypeLong) values
-+++ ("F","Full"),
-+++ ("D","Diff"),
-+++ ("I","Inc");
-++ - Add ACL to restore only to original location.
-++ - Add a recursive mark command (rmark) to restore.
-++ - "Minimum Job Interval = nnn" sets minimum interval between Jobs
-++@@ -1246,219 +1252,4 @@
-++ ====
-++
-++
-++-=== Done
-++-- Save mount point for directories not traversed with onefs=yes.
-++-- Add seconds to start and end times in the Job report output.
-++-- if 2 concurrent backups are attempted on the same tape
-++- drive (autoloader) into different tape pools, one of them will exit
-++- fatally instead of halting until the drive is idle
-++-- Update StartTime if job held in Job Queue.
-++-- Look at www.nu2.nu/pebuilder as a helper for full windows
-++- bare metal restore. (done by Scott)
-++-- Fix orphanned buffers:
-++- Orphaned buffer: 24 bytes allocated at line 808 of rufus-dir job.c
-++- Orphaned buffer: 40 bytes allocated at line 45 of rufus-dir alist.c
-++-- Implement Preben's suggestion to add
-++- File System Types = ext2, ext3
-++- to FileSets, thus simplifying backup of *all* local partitions.
-++-- Try to open a device on each Job if it was not opened
-++- when the SD started.
-++-- Add dump of VolSessionId/Time and FileIndex with bls.
-++-- If Bacula does not find the right tape in the Autochanger,
-++- then mark the tape in error and move on rather than asking
-++- for operator intervention.
-++-- Cancel command should include JobId in list of Jobs.
-++-- Add performance testing hooks
-++-- Bootstrap from JobMedia records.
-++-- Implement WildFile and WildDir to solve problem of
-++- saving only *.doc files.
-++-- Fix
-++- Please use the "label" command to create a new Volume for:
-++- Storage: DDS-4-changer
-++- Media type:
-++- Pool: Default
-++- label
-++- The defined Storage resources are:
-++-- Copy Changer Device and Changer Command from Autochanger
-++- to Device resource in SD if none given in Device resource.
-++-- 1. Automatic use of more than one drive in an autochanger (done)
-++-- 2. Automatic selection of the correct drive for each Job (i.e.
-++- selects a drive with an appropriate Volume for the Job) (done)
-++-- 6. Allow multiple simultaneous Jobs referencing the same pool write
-++- to several tapes (some new directive(s) are are probably needed for
-++- this) (done)
-++-- Locking (done)
-++-- Key on Storage rather than Pool (done)
-++-- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
-++-- Synchronize multiple drives so that not more
-++- than one loads a tape and any time (done)
-++-- 4. Use Changer Device and Changer Command specified in the
-++- Autochanger resource, if none is found in the Device resource.
-++- You can continue to specify them in the Device resource if you want
-++- or need them to be different for each device.
-++-- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
-++- that can allow a Device be part of an Autochanger, and hence the changer
-++- script protected, but if set to no, will prevent the Device from being
-++- automatically selected from the changer. This allows the device to
-++- be directly accessed through its Device name, but not through the
-++- AutoChanger name.
-++-#6 Select one from among Multiple Storage Devices for Job
-++-#5 Events that call a Python program
-++- (Implemented in Dir/SD)
-++-- Make sure the Device name is in the Query packet returned.
-++-- Don't start a second file job if one is already running.
-++-- Implement EOF/EOV labels for ANSI labels
-++-- Implement IBM labels.
-++-- When Python creates a new label, the tape is immediately
-++- recycled and no label created. This happens when using
-++- autolabeling -- even when Python doesn't generate the name.
-++-- Scratch Pool where the volumes can be re-assigned to any Pool.
-++-- 28-Mar 23:19 rufus-sd: acquire.c:379 Device "DDS-4" (/dev/nst0)
-++- is busy reading. Job 6 canceled.
-++-- Remove separate thread for opening devices in SD. On the other
-++- hand, don't block waiting for open() for devices.
-++-- Fix code to either handle updating NumVol or to calculate it in
-++- Dir next_vol.c
-++-- Ensure that you cannot exclude a directory or a file explicitly
-++- Included with File.
-++-#4 Embedded Python Scripting
-++- (Implemented in Dir/SD/FD)
-++-- Add Python writable variable for changing the Priority,
-++- Client, Storage, JobStatus (error), ...
-++-- SD Python
-++- - Solicit Events
-++-- Add disk seeking on restore; turn off seek on tapes.
-++- stored/match_bsr.c
-++-- Look at dird_conf.c:1000: warning: `int size'
-++- might be used uninitialized in this function
-++-- Indicate when a Job is purged/pruned during restore.
-++-- Implement some way to turn off automatic pruning in Jobs.
-++-- Implement a way an Admin Job can prune, possibly multiple
-++- clients -- Python script?
-++-- Look at Preben's acl.c error handling code.
-++-- SD crashes after a tape restore then doing a backup.
-++-- If drive is opened read/write, close it and re-open
-++- read-only if doing a restore, and vice-versa.
-++-- Windows restore:
-++- data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
-++- > ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
-++- > Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen
-++- > Prozess verwendet wird.
-++- Restore restores all files, but then fails at the end trying
-++- to set the attributes of e:
-++- from failed jobs.- Resolve the problem between Device name and Archive name,
-++- and fix SD messages.
-++-- Tell the "restore" user when browsing is no longer possible.
-++-- Add a restore directory-x
-++-- Write non-optimized bsrs from the JobMedia and Media records,
-++- even after Files are pruned.
-++-- Delete Stripe and Copy from VolParams to save space.
-++-- Fix option 2 of restore -- list where file is backed up -- require Client,
-++- then list last 20 backups.
-++-- Finish implementation of passing all Storage and Device needs to
-++- the SD.
-++-- Move test for max wait time exceeded in job.c up -- Peter's idea.
-++-## Consider moving docs to their own project.
-++-## Move rescue to its own project.
-++-- Add client version to the Client name line that prints in
-++- the Job report.
-++-- Fix the Rescue CDROM.
-++-- By the way: on page http://www.bacula.org/?page=tapedrives , at the
-++- bottom, the link to "Tape Testing Chapter" is broken. It goes to
-++- /html-manual/... while the others point to /rel-manual/...
-++-- Device resource needs the "name" of the SD.
-++-- Specify a single directory to restore.
-++-- Implement MediaType keyword in bsr?
-++-- Add a date and time stamp at the beginning of every line in the
-++- Job report (Volker Sauer).
-++-- Add level to estimate command.
-++-- Add "limit=n" for "list jobs"
-++-- Make bootstrap filename unique.
-++-- Make Dmsg look at global before calling subroutine.
-++-- From Chris Hull:
-++- it seems to be complaining about 12:00pm which should be a valid 12
-++- hour time. I changed the time to 11:59am and everything works fine.
-++- Also 12:00am works fine. 0:00pm also works (which I don't think
-++- should). None of the values 12:00pm - 12:59pm work for that matter.
-++-- Require restore via the restore command or make a restore Job
-++- get the bootstrap file.
-++-- Implement Maximum Job Spool Size
-++-- Fix 3993 error in SD. It forgets to look at autochanger
-++- resource for device command, ...
-++-- 3. Prevent two drives requesting the same Volume in any given
-++- autochanger, by checking if a Volume is mounted on another drive
-++- in an Autochanger.
-++-- Upgrade to MySQL 4.1.12 See:
-++- http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
-++-- Add # Job Level date to bsr file
-++-- Implement "PreferMountedVolumes = yes|no" in Job resource.
-++-## Integrate web-bacula into a new Bacula project with
-++- bimagemgr.
-++-- Cleaning tapes should have Status "Cleaning" rather than append.
-++-- Make sure that Python has access to Client address/port so that
-++- it can check if Clients are alive.
-++-- Review all items in "restore".
-++-- Fix PostgreSQL GROUP BY problems in restore.
-++-- Fix PostgreSQL sql problems in bugs.
-++-- After rename
-++- 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume
-++- "DLT-13Feb04".
-++- Current Volume "DLT-04Jul05" not acceptable because:
-++- 1997 Volume "DLT-13Feb04" not in catalog.
-++- 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device
-++- "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
-++-## Create a new GUI chapter explaining all the GUI programs.
-++-- Make "update slots" when pointing to Autochanger, remove
-++- all Volumes from other drives. "update slots all-drives"?
-++- No, this is done by modifying mtx-changer to list what is
-++- in the drives.
-++-- Finish TLS implementation.
-++-- Port limiting -m in iptables to prevent DoS attacks
-++- could cause broken pipes on Bacula.
-++-6. Build and test the Volume Shadow Copy (VSS) for Win32.
-++-- Allow cancel of unknown Job
-++-- State not saved when closing Win32 FD by icon
-++-- bsr-opt-test fails. bsr deleted. Fix.
-++-- Move Python daemon variables from Job to Bacula object.
-++- WorkingDir, ConfigFile
-++-- Document that Bootstrap files can be written with cataloging
-++- turned off.
-++-- Document details of ANSI/IBM labels
-++-- OS linux 2.4
-++- 1) ADIC, DLT, FastStor 4000, 7*20GB
-++-- Linux Sony LIB-D81, AIT-3 library works.
-++-- Doc the following
-++- to activate, check or disable the hardware compression feature on my
-++- exb-8900 i use the exabyte "MammothTool" you can get it here:
-++- http://www.exabyte.com/support/online/downloads/index.cfm
-++- There is a solaris version of this tool. With option -C 0 or 1 you can
-++- disable or activate compression. Start this tool without any options for
-++- a small reference.
-++-- Document Heartbeat Interval in the dealing with firewalls section.
-++-- Document new CDROM directory.
-++-- On Win32 working directory must have drive letter ????
-++-- On Win32 working directory must be writable by SYSTEM to
-++- do restores.
-++-- Document that ChangerDevice is used for Alert command.
-++-- Add better documentation on how restores can be done
-++-8. Take one more try at making DVD writing work (no go)
-++-7. Write a bacula-web document
-++-- Why isn't the DEVICE structure defined when doing
-++- a reservation?
-++-- Multi-drive changer seems to only use drive 0
-++- Multiple drives don't seem to be opened.
-++-- My database is growing
-++-- Call GetLastError() in the berrno constructor rather
-++- than delaying until strerror.
-++-- Tape xxx in drive 0, requested in drive 1
-++-- The mount command does not work with drives other than 0.
-++-- A mount should cause the SD to re-examine what Slot is
-++- loaded.
-++-- The SD locks on to the first available drive then
-++- wants a Volume that is released but in another drive --
-++- chaos.
-++-- Run the regression scripts on Solaris and FreeBSD
-++-- Figure out how to package gui, and rescue programs.
-++-- Add a .dir command to restore tree code to eliminate the problem
-++-- Mount after manually unloading changer causes hang in SD
-++-- Fix JobACL with restore by JobId.
-+++=== Done -- see kernsdone
-++Index: kes-1.38
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-++retrieving revision 1.1.2.13
-++diff -u -r1.1.2.13 kes-1.38
-++--- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-+++++ kes-1.38 22 Nov 2005 10:42:20 -0000
-++@@ -3,6 +3,19 @@
-++
-++ General:
-++
-+++Changes to 1.38.2:
-+++20Oct05
-+++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+++ says this does not fix *his* bug).
-+++- Fix cancel failure bug. Bug #481
-+++- Fix failure when Pool name has spaces. Bug #487
-+++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++- Fix a couple of free()s in src/filed/acl.c
-+++- Fix memory overrun in bfile.c in building OS X resource
-+++ fork filename. Bug #489
-+++- Add Pool name to SD status output.
-+++
-++ Changes to 1.38.1:
-++ 14Oct05
-++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-++Index: projects
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/projects,v
-++retrieving revision 1.12.2.3
-++diff -u -r1.12.2.3 projects
-++--- projects 10 Nov 2005 20:25:27 -0000 1.12.2.3
-+++++ projects 22 Nov 2005 10:42:20 -0000
-++@@ -228,7 +228,175 @@
-++
-++ Why: Performance enhancement.
-++
-+++Item 13: Let Bacula log tape usage and handle drive cleaning cycles.
-+++ Date: November 11, 2005
-+++ Origin: Arno Lehmann <al at its-lehmann dot de>
-+++ Status:
-+++
-+++ What: Make Bacula manage tape life cycle information and drive
-+++ cleaning cycles.
-+++
-+++ Why: Both parts of this project are important when operating backups.
-+++ We need to know which tapes need replacement, and we need to
-+++ make sure the drives are cleaned when necessary. While many
-+++ tape libraries and even autoloaders can handle all this
-+++ automatically, support by Bacula can be helpful for smaller
-+++ (older) libraries and single drives. Also, checking drive
-+++ status during operation can prevent some failures (as I had to
-+++ learn the hard way...)
-+++
-+++ Notes: First, Bacula could (and even does, to some limited extent)
-+++ record tape and drive usage. For tapes, the number of mounts,
-+++ the amount of data, and the time the tape has actually been
-+++ running could be recorded. Data fields for Read and Write time
-+++ and Nmber of mounts already exist in the catalog (I'm not sure
-+++ if VolBytes is the sum of all bytes ever written to that volume
-+++ by Bacula). This information can be important when determining
-+++ which media to replace. For the tape drives known to Bacula,
-+++ similar information is interesting to determine the device
-+++ status and expected life time: Time it's been Reading and
-+++ Writing, number of tape Loads / Unloads / Errors. This
-+++ information is not yet recorded as far as I know.
-+++
-+++ The next step would be implementing drive cleaning setup.
-+++ Bacula already has knowledge about cleaning tapes. Once it has
-+++ some information about cleaning cycles (measured in drive run
-+++ time, number of tapes used, or calender days, for example) it
-+++ can automatically execute tape cleaning (with an autochanger,
-+++ obviously) or ask for operator assistence loading a cleaning
-+++ tape.
-+++
-+++ The next step would be to implement TAPEALERT checks not only
-+++ when changing tapes and only sending he information to the
-+++ administrator, but rather checking after each tape error,
-+++ checking on a regular basis (for example after each tape file),
-+++ and also before unloading and after loading a new tape. Then,
-+++ depending on the drives TAPEALERT state and the know drive
-+++ cleaning state Bacula could automatically schedule later
-+++ cleaning, clean immediately, or inform the operator.
-+++
-+++ Implementing this would perhaps require another catalog change
-+++ and perhaps major changes in SD code and the DIR-SD protocoll,
-+++ so I'd only consider this worth implementing if it would
-+++ actually be used or even needed by many people.
-+++
-+++Item 14: Merging of multiple backups into a single one. (Also called Synthetic
-+++ Backup or Consolidation).
-+++
-+++ Origin: Marc Cousin and Eric Bollengier
-+++ Date: 15 November 2005
-+++ Status: Depends on first implementing project Item 1 (Migration).
-+++
-+++ What: A merged backup is a backup made without connecting to the Client.
-+++ It would be a Merge of existing backups into a single backup.
-+++ In effect, it is like a restore but to the backup medium.
-+++
-+++ For instance, say that last sunday we made a full backup. Then
-+++ all week long, we created incremental backups, in order to do
-+++ them fast. Now comes sunday again, and we need another full.
-+++ The merged backup makes it possible to do instead an incremental
-+++ backup (during the night for instance), and then create a merged
-+++ backup during the day, by using the full and incrementals from
-+++ the week. The merged backup will be exactly like a full made
-+++ sunday night on the tape, but the production interruption on the
-+++ Client will be minimal, as the Client will only have to send
-+++ incrementals.
-+++
-+++ In fact, if it's done correctly, you could merge all the
-+++ Incrementals into single Incremental, or all the Incrementals
-+++ and the last Differential into a new Differential, or the Full,
-+++ last differential and all the Incrementals into a new Full
-+++ backup. And there is no need to involve the Client.
-+++
-+++ Why: The benefit is that :
-+++ - the Client just does an incremental ;
-+++ - the merged backup on tape is just as a single full backup,
-+++ and can be restored very fast.
-+++
-+++ This is also a way of reducing the backup data since the old
-+++ data can then be pruned (or not) from the catalog, possibly
-+++ allowing older volumes to be recycled
-+++
-+++Item 15: Automatic disabling of devices
-+++ Date: 2005-11-11
-+++ Origin: Peter Eriksson <peter at ifm.liu dot se>
-+++ Status:
-+++
-+++ What: After a configurable amount of fatal errors with a tape drive
-+++ Bacula should automatically disable further use of a certain
-+++ tape drive. There should also be "disable"/"enable" commands in
-+++ the "bconsole" tool.
-+++
-+++ Why: On a multi-drive jukebox there is a possibility of tape drives
-+++ going bad during large backups (needing a cleaning tape run,
-+++ tapes getting stuck). It would be advantageous if Bacula would
-+++ automatically disable further use of a problematic tape drive
-+++ after a configurable amount of errors has occured.
-+++
-+++ An example: I have a multi-drive jukebox (6 drives, 380+ slots)
-+++ where tapes occasionally get stuck inside the drive. Bacula will
-+++ notice that the "mtx-changer" command will fail and then fail
-+++ any backup jobs trying to use that drive. However, it will still
-+++ keep on trying to run new jobs using that drive and fail -
-+++ forever, and thus failing lots and lots of jobs... Since we have
-+++ many drives Bacula could have just automatically disabled
-+++ further use of that drive and used one of the other ones
-+++ instead.
-+++
-+++
-+++Item 16: Directive/mode to backup only file changes, not entire file
-+++ Date: 11 November 2005
-+++ Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
-+++ Marek Bajon <mbajon at bimsplus dot com dot pl>
-+++ Status: RFC
-+++
-+++ What: Currently when a file changes, the entire file will be backed up in
-+++ the next incremental or full backup. To save space on the tapes
-+++ it would be nice to have a mode whereby only the changes to the
-+++ file would be backed up when it is changed.
-+++
-+++ Why: This would save lots of space when backing up large files such as
-+++ logs, mbox files, Outlook PST files and the like.
-+++
-+++ Notes: This would require the usage of disk-based volumes as comparing
-+++ files would not be feasible using a tape drive.
-+++
-+++Item 17: Quick release of FD-SD connection
-+++ Origin: Frank Volf (frank at deze dot org)
-+++ Date: 17 november 2005
-+++ Status:
-+++
-+++ What: In the bacula implementation a backup is finished after all data
-+++ and attributes are succesfully written to storage. When using a
-+++ tape backup it is very annoying that a backup can take a day,
-+++ simply because the current tape (or whatever) is full and the
-+++ administrator has not put a new one in. During that time the
-+++ system cannot be taken off-line, because there is still an open
-+++ session between the storage daemon and the file daemon on the
-+++ client.
-+++
-+++ Although this is a very good strategey for making "safe backups"
-+++ This can be annoying for e.g. laptops, that must remain
-+++ connected until the bacukp is completed.
-+++
-+++ Using a new feature called "migration" it will be possible to
-+++ spool first to harddisk (using a special 'spool' migration
-+++ scheme) and then migrate the backup to tape.
-+++
-+++ There is still the problem of getting the attributes committed.
-+++ If it takes a very long time to do, with the current code, the
-+++ job has not terminated, and the File daemon is not freed up. The
-+++ Storage daemon should release the File daemon as soon as all the
-+++ file data and all the attributes have been sent to it (the SD).
-+++ Currently the SD waits until everything is on tape and all the
-+++ attributes are transmitted to the Director before signalling
-+++ completion to the FD. I don't think I would have any problem
-+++ changing this. The reason is that even if the FD reports back to
-+++ the Dir that all is OK, the job will not terminate until the SD
-+++ has done the same thing -- so in a way keeping the SD-FD link
-+++ open to the very end is not really very productive ...
-++
-+++ Why: Makes backup of laptops much easier.
-++
-++
-++ ============= Empty RFC form ===========
-++@@ -245,33 +413,4 @@
-++ ============== End RFC form ==============
-++
-++
-++-Items completed for release 1.38.0:
-++-#4 Embedded Python Scripting (implemented in all Daemons)
-++-#5 Events that call a Python program (Implemented in all
-++- daemons, but more cleanup work to be done).
-++-#6 Select one from among Multiple Storage Devices for Job.
-++- This is already implemented in 1.37.
-++-#7 Single Job Writing to Multiple Storage Devices. This is
-++- currently implemented with a Clone feature.
-++-#- Full multiple drive Autochanger support (done in 1.37)
-++-#- Built in support for communications encryption (TLS)
-++- done by Landon Fuller.
-++-# Support for Unicode characters
-++- (via UTF-8) on Win32 machines thanks to Thorsten Engel.
-++-Item 8: Break the one-to-one Relationship between a Job and a
-++- Specific Storage Device (or Devices if #10 is implemented).
-++-
-++-Completed items from last year's list:
-++-Item 1: Multiple simultaneous Jobs. (done)
-++-Item 3: Write the bscan program -- also write a bcopy program (done).
-++-Item 5: Implement Label templates (done).
-++-Item 6: Write a regression script (done)
-++-Item 9: Add SSL to daemon communications (done by Landon Fuller)
-++-Item 10: Define definitive tape format (done)
-++-Item 3: GUI for interactive restore. Partially Implemented in 1.34
-++- Note, there is now a complete Webmin plugin, a partial
-++- GNOME console, and an excellent wx-console GUI.
-++-Item 4: GUI for interactive backup
-++-Item 2: Job Data Spooling.
-++- Done: Regular expression matching.
-++-Item 10: New daemon communication protocol (this has been dropped).
-+++Items completed for release 1.38.0 -- see kernsdone
-++Index: autoconf/configure.in
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/autoconf/configure.in,v
-++retrieving revision 1.184.2.4
-++diff -u -r1.184.2.4 configure.in
-++--- autoconf/configure.in 13 Nov 2005 10:51:17 -0000 1.184.2.4
-+++++ autoconf/configure.in 22 Nov 2005 10:42:21 -0000
-++@@ -604,7 +604,7 @@
-++ PYTHON_LIBS=
-++ if test "$withval" != "no"; then
-++ if test "$withval" = "yes"; then
-++- for python_root in /usr /usr/local; do
-+++ for python_root in /usr /usr/local /usr/sfw; do
-++ if test -f $python_root/include/python2.2/Python.h; then
-++ PYTHON_INCDIR=-I$python_root/include/python2.2
-++ PYTHON_LIBS="-L$python_root/lib/python2.2/config -lpython2.2"
-++Index: patches/1.38.1-to-1.38.2.patch
-++===================================================================
-++RCS file: patches/1.38.1-to-1.38.2.patch
-++diff -N patches/1.38.1-to-1.38.2.patch
-++--- /dev/null 1 Jan 1970 00:00:00 -0000
-+++++ patches/1.38.1-to-1.38.2.patch 22 Nov 2005 10:42:22 -0000
-++@@ -0,0 +1,4586 @@
-+++
-+++ This patch fixes the following bugs:
-+++
-+++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+++ says that this patch does not fix his problem)
-+++- Fix cancel failure bug. Bug #481
-+++- Fix failure when Pool name has spaces. Bug #487
-+++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++- Fix a couple of free()s in src/filed/acl.c
-+++- Fix memory overrun in bfile.c in building OS X resource
-+++ fork filename. Bug #489
-+++
-+++This patch is applied to Bacula source version 1.38.1 and will
-+++produce Bacula source version 1.38.2. Apply it with:
-+++
-+++ cd <bacula-1.38.1-source>
-+++ ./configure (your options) if not already done
-+++ patch -p0 <1.38.1-to-1.38.2.patch
-+++ make
-+++ make install
-+++
-+++? osx_finder.patch
-+++Index: ChangeLog
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/ChangeLog,v
-+++retrieving revision 1.154.2.7
-+++diff -u -r1.154.2.7 ChangeLog
-+++--- ChangeLog 15 Nov 2005 09:27:19 -0000 1.154.2.7
-++++++ ChangeLog 21 Nov 2005 18:19:03 -0000
-+++@@ -1,4 +1,14 @@
-+++
-++++Changes to 1.38.2:
-++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++- Fix bnet-server bug found on OpenBSD. Bug #486
-++++- Fix cancel failure bug. Bug #481
-++++- Fix failure when Pool name has spaces. Bug #487
-++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++- Fix a couple of free()s in src/filed/acl.c
-++++- Fix memory overrun in bfile.c in building OS X resource
-++++ fork filename. Bug #489
-++++- Add Pool name to SD status output.
-+++
-+++ Changes to 1.38.1:
-+++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-+++Index: ReleaseNotes
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/ReleaseNotes,v
-+++retrieving revision 1.147.2.9
-+++diff -u -r1.147.2.9 ReleaseNotes
-+++--- ReleaseNotes 15 Nov 2005 09:27:19 -0000 1.147.2.9
-++++++ ReleaseNotes 21 Nov 2005 18:19:04 -0000
-+++@@ -1,10 +1,21 @@
-+++
-+++- Release Notes for Bacula 1.38.1
-++++ Release Notes for Bacula 1.38.2
-+++
-+++ Bacula code: Total files = 420 Total lines = 138,440 (*.h *.c *.in)
-+++ 20,440 additional lines of code since version 1.36.3
-+++
-+++-Changes since 1.38.0:
-++++Changes to 1.38.2:
-++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++- Fix bnet-server bug found on OpenBSD. Bug #486
-++++- Fix cancel failure bug. Bug #481
-++++- Fix failure when Pool name has spaces. Bug #487
-++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++- Fix a couple of free()s in src/filed/acl.c
-++++- Fix memory overrun in bfile.c in building OS X resource
-++++ fork filename. Bug #489
-++++- Add Pool name to SD status output.
-++++
-++++Changes to 1.38.1:
-+++ - Corrected ACL for Solaris (David Duchscher and Attila Fulop).
-+++ - Add bacula_mail_summary.sh to examples directory. It makes
-+++ a single email summary of any number of jobs. Submitted
-+++Index: kernstodo
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/kernstodo,v
-+++retrieving revision 1.570.2.6
-+++diff -u -r1.570.2.6 kernstodo
-+++--- kernstodo 4 Nov 2005 09:16:49 -0000 1.570.2.6
-++++++ kernstodo 21 Nov 2005 18:19:04 -0000
-+++@@ -1,5 +1,5 @@
-+++ Kern's ToDo List
-+++- 03 November 2005
-++++ 21 November 2005
-+++
-+++ Major development:
-+++ Project Developer
-+++@@ -7,8 +7,6 @@
-+++ Version 1.37 Kern (see below)
-+++ ========================================================
-+++
-+++-Final items for 1.37 before release:
-+++-
-+++ Document:
-+++ - Does ClientRunAfterJob fail the job on a bad return code?
-+++ - Document cleaning up the spool files:
-+++@@ -18,6 +16,8 @@
-+++ - Does WildFile match against full name? Doc.
-+++
-+++ For 1.39:
-++++- Make sure that all do_prompt() calls in Dir check for
-++++ -1 (error) and -2 (cancel) returns.
-+++ - Look at -D_FORTIFY_SOURCE=2
-+++ - Add Win32 FileSet definition somewhere
-+++ - Look at fixing restore status stats in SD.
-+++@@ -27,6 +27,12 @@
-+++ encountered, read many times (as it currently does), and if the
-+++ block cannot be read, skip to the next block, and try again. If
-+++ that fails, skip to the next file and try again, ...
-++++- Add level table:
-++++ create table LevelType (LevelType binary(1), LevelTypeLong tinyblob);
-++++ insert into LevelType (LevelType,LevelTypeLong) values
-++++ ("F","Full"),
-++++ ("D","Diff"),
-++++ ("I","Inc");
-+++ - Add ACL to restore only to original location.
-+++ - Add a recursive mark command (rmark) to restore.
-+++ - "Minimum Job Interval = nnn" sets minimum interval between Jobs
-+++@@ -1246,219 +1252,4 @@
-+++ ====
-+++
-+++
-+++-=== Done
-+++-- Save mount point for directories not traversed with onefs=yes.
-+++-- Add seconds to start and end times in the Job report output.
-+++-- if 2 concurrent backups are attempted on the same tape
-+++- drive (autoloader) into different tape pools, one of them will exit
-+++- fatally instead of halting until the drive is idle
-+++-- Update StartTime if job held in Job Queue.
-+++-- Look at www.nu2.nu/pebuilder as a helper for full windows
-+++- bare metal restore. (done by Scott)
-+++-- Fix orphanned buffers:
-+++- Orphaned buffer: 24 bytes allocated at line 808 of rufus-dir job.c
-+++- Orphaned buffer: 40 bytes allocated at line 45 of rufus-dir alist.c
-+++-- Implement Preben's suggestion to add
-+++- File System Types = ext2, ext3
-+++- to FileSets, thus simplifying backup of *all* local partitions.
-+++-- Try to open a device on each Job if it was not opened
-+++- when the SD started.
-+++-- Add dump of VolSessionId/Time and FileIndex with bls.
-+++-- If Bacula does not find the right tape in the Autochanger,
-+++- then mark the tape in error and move on rather than asking
-+++- for operator intervention.
-+++-- Cancel command should include JobId in list of Jobs.
-+++-- Add performance testing hooks
-+++-- Bootstrap from JobMedia records.
-+++-- Implement WildFile and WildDir to solve problem of
-+++- saving only *.doc files.
-+++-- Fix
-+++- Please use the "label" command to create a new Volume for:
-+++- Storage: DDS-4-changer
-+++- Media type:
-+++- Pool: Default
-+++- label
-+++- The defined Storage resources are:
-+++-- Copy Changer Device and Changer Command from Autochanger
-+++- to Device resource in SD if none given in Device resource.
-+++-- 1. Automatic use of more than one drive in an autochanger (done)
-+++-- 2. Automatic selection of the correct drive for each Job (i.e.
-+++- selects a drive with an appropriate Volume for the Job) (done)
-+++-- 6. Allow multiple simultaneous Jobs referencing the same pool write
-+++- to several tapes (some new directive(s) are are probably needed for
-+++- this) (done)
-+++-- Locking (done)
-+++-- Key on Storage rather than Pool (done)
-+++-- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
-+++-- Synchronize multiple drives so that not more
-+++- than one loads a tape and any time (done)
-+++-- 4. Use Changer Device and Changer Command specified in the
-+++- Autochanger resource, if none is found in the Device resource.
-+++- You can continue to specify them in the Device resource if you want
-+++- or need them to be different for each device.
-+++-- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
-+++- that can allow a Device be part of an Autochanger, and hence the changer
-+++- script protected, but if set to no, will prevent the Device from being
-+++- automatically selected from the changer. This allows the device to
-+++- be directly accessed through its Device name, but not through the
-+++- AutoChanger name.
-+++-#6 Select one from among Multiple Storage Devices for Job
-+++-#5 Events that call a Python program
-+++- (Implemented in Dir/SD)
-+++-- Make sure the Device name is in the Query packet returned.
-+++-- Don't start a second file job if one is already running.
-+++-- Implement EOF/EOV labels for ANSI labels
-+++-- Implement IBM labels.
-+++-- When Python creates a new label, the tape is immediately
-+++- recycled and no label created. This happens when using
-+++- autolabeling -- even when Python doesn't generate the name.
-+++-- Scratch Pool where the volumes can be re-assigned to any Pool.
-+++-- 28-Mar 23:19 rufus-sd: acquire.c:379 Device "DDS-4" (/dev/nst0)
-+++- is busy reading. Job 6 canceled.
-+++-- Remove separate thread for opening devices in SD. On the other
-+++- hand, don't block waiting for open() for devices.
-+++-- Fix code to either handle updating NumVol or to calculate it in
-+++- Dir next_vol.c
-+++-- Ensure that you cannot exclude a directory or a file explicitly
-+++- Included with File.
-+++-#4 Embedded Python Scripting
-+++- (Implemented in Dir/SD/FD)
-+++-- Add Python writable variable for changing the Priority,
-+++- Client, Storage, JobStatus (error), ...
-+++-- SD Python
-+++- - Solicit Events
-+++-- Add disk seeking on restore; turn off seek on tapes.
-+++- stored/match_bsr.c
-+++-- Look at dird_conf.c:1000: warning: `int size'
-+++- might be used uninitialized in this function
-+++-- Indicate when a Job is purged/pruned during restore.
-+++-- Implement some way to turn off automatic pruning in Jobs.
-+++-- Implement a way an Admin Job can prune, possibly multiple
-+++- clients -- Python script?
-+++-- Look at Preben's acl.c error handling code.
-+++-- SD crashes after a tape restore then doing a backup.
-+++-- If drive is opened read/write, close it and re-open
-+++- read-only if doing a restore, and vice-versa.
-+++-- Windows restore:
-+++- data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
-+++- > ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
-+++- > Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen
-+++- > Prozess verwendet wird.
-+++- Restore restores all files, but then fails at the end trying
-+++- to set the attributes of e:
-+++- from failed jobs.- Resolve the problem between Device name and Archive name,
-+++- and fix SD messages.
-+++-- Tell the "restore" user when browsing is no longer possible.
-+++-- Add a restore directory-x
-+++-- Write non-optimized bsrs from the JobMedia and Media records,
-+++- even after Files are pruned.
-+++-- Delete Stripe and Copy from VolParams to save space.
-+++-- Fix option 2 of restore -- list where file is backed up -- require Client,
-+++- then list last 20 backups.
-+++-- Finish implementation of passing all Storage and Device needs to
-+++- the SD.
-+++-- Move test for max wait time exceeded in job.c up -- Peter's idea.
-+++-## Consider moving docs to their own project.
-+++-## Move rescue to its own project.
-+++-- Add client version to the Client name line that prints in
-+++- the Job report.
-+++-- Fix the Rescue CDROM.
-+++-- By the way: on page http://www.bacula.org/?page=tapedrives , at the
-+++- bottom, the link to "Tape Testing Chapter" is broken. It goes to
-+++- /html-manual/... while the others point to /rel-manual/...
-+++-- Device resource needs the "name" of the SD.
-+++-- Specify a single directory to restore.
-+++-- Implement MediaType keyword in bsr?
-+++-- Add a date and time stamp at the beginning of every line in the
-+++- Job report (Volker Sauer).
-+++-- Add level to estimate command.
-+++-- Add "limit=n" for "list jobs"
-+++-- Make bootstrap filename unique.
-+++-- Make Dmsg look at global before calling subroutine.
-+++-- From Chris Hull:
-+++- it seems to be complaining about 12:00pm which should be a valid 12
-+++- hour time. I changed the time to 11:59am and everything works fine.
-+++- Also 12:00am works fine. 0:00pm also works (which I don't think
-+++- should). None of the values 12:00pm - 12:59pm work for that matter.
-+++-- Require restore via the restore command or make a restore Job
-+++- get the bootstrap file.
-+++-- Implement Maximum Job Spool Size
-+++-- Fix 3993 error in SD. It forgets to look at autochanger
-+++- resource for device command, ...
-+++-- 3. Prevent two drives requesting the same Volume in any given
-+++- autochanger, by checking if a Volume is mounted on another drive
-+++- in an Autochanger.
-+++-- Upgrade to MySQL 4.1.12 See:
-+++- http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
-+++-- Add # Job Level date to bsr file
-+++-- Implement "PreferMountedVolumes = yes|no" in Job resource.
-+++-## Integrate web-bacula into a new Bacula project with
-+++- bimagemgr.
-+++-- Cleaning tapes should have Status "Cleaning" rather than append.
-+++-- Make sure that Python has access to Client address/port so that
-+++- it can check if Clients are alive.
-+++-- Review all items in "restore".
-+++-- Fix PostgreSQL GROUP BY problems in restore.
-+++-- Fix PostgreSQL sql problems in bugs.
-+++-- After rename
-+++- 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume
-+++- "DLT-13Feb04".
-+++- Current Volume "DLT-04Jul05" not acceptable because:
-+++- 1997 Volume "DLT-13Feb04" not in catalog.
-+++- 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device
-+++- "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
-+++-## Create a new GUI chapter explaining all the GUI programs.
-+++-- Make "update slots" when pointing to Autochanger, remove
-+++- all Volumes from other drives. "update slots all-drives"?
-+++- No, this is done by modifying mtx-changer to list what is
-+++- in the drives.
-+++-- Finish TLS implementation.
-+++-- Port limiting -m in iptables to prevent DoS attacks
-+++- could cause broken pipes on Bacula.
-+++-6. Build and test the Volume Shadow Copy (VSS) for Win32.
-+++-- Allow cancel of unknown Job
-+++-- State not saved when closing Win32 FD by icon
-+++-- bsr-opt-test fails. bsr deleted. Fix.
-+++-- Move Python daemon variables from Job to Bacula object.
-+++- WorkingDir, ConfigFile
-+++-- Document that Bootstrap files can be written with cataloging
-+++- turned off.
-+++-- Document details of ANSI/IBM labels
-+++-- OS linux 2.4
-+++- 1) ADIC, DLT, FastStor 4000, 7*20GB
-+++-- Linux Sony LIB-D81, AIT-3 library works.
-+++-- Doc the following
-+++- to activate, check or disable the hardware compression feature on my
-+++- exb-8900 i use the exabyte "MammothTool" you can get it here:
-+++- http://www.exabyte.com/support/online/downloads/index.cfm
-+++- There is a solaris version of this tool. With option -C 0 or 1 you can
-+++- disable or activate compression. Start this tool without any options for
-+++- a small reference.
-+++-- Document Heartbeat Interval in the dealing with firewalls section.
-+++-- Document new CDROM directory.
-+++-- On Win32 working directory must have drive letter ????
-+++-- On Win32 working directory must be writable by SYSTEM to
-+++- do restores.
-+++-- Document that ChangerDevice is used for Alert command.
-+++-- Add better documentation on how restores can be done
-+++-8. Take one more try at making DVD writing work (no go)
-+++-7. Write a bacula-web document
-+++-- Why isn't the DEVICE structure defined when doing
-+++- a reservation?
-+++-- Multi-drive changer seems to only use drive 0
-+++- Multiple drives don't seem to be opened.
-+++-- My database is growing
-+++-- Call GetLastError() in the berrno constructor rather
-+++- than delaying until strerror.
-+++-- Tape xxx in drive 0, requested in drive 1
-+++-- The mount command does not work with drives other than 0.
-+++-- A mount should cause the SD to re-examine what Slot is
-+++- loaded.
-+++-- The SD locks on to the first available drive then
-+++- wants a Volume that is released but in another drive --
-+++- chaos.
-+++-- Run the regression scripts on Solaris and FreeBSD
-+++-- Figure out how to package gui, and rescue programs.
-+++-- Add a .dir command to restore tree code to eliminate the problem
-+++-- Mount after manually unloading changer causes hang in SD
-+++-- Fix JobACL with restore by JobId.
-++++=== Done -- see kernsdone
-+++Index: kes-1.38
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-+++retrieving revision 1.1.2.13
-+++diff -u -r1.1.2.13 kes-1.38
-+++--- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-++++++ kes-1.38 21 Nov 2005 18:19:04 -0000
-+++@@ -3,6 +3,19 @@
-+++
-+++ General:
-+++
-++++Changes to 1.38.2:
-++++20Oct05
-++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++++ says this does not fix *his* bug).
-++++- Fix cancel failure bug. Bug #481
-++++- Fix failure when Pool name has spaces. Bug #487
-++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++- Fix a couple of free()s in src/filed/acl.c
-++++- Fix memory overrun in bfile.c in building OS X resource
-++++ fork filename. Bug #489
-++++- Add Pool name to SD status output.
-++++
-+++ Changes to 1.38.1:
-+++ 14Oct05
-+++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-+++Index: projects
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/projects,v
-+++retrieving revision 1.12.2.3
-+++diff -u -r1.12.2.3 projects
-+++--- projects 10 Nov 2005 20:25:27 -0000 1.12.2.3
-++++++ projects 21 Nov 2005 18:19:05 -0000
-+++@@ -228,7 +228,175 @@
-+++
-+++ Why: Performance enhancement.
-+++
-++++Item 13: Let Bacula log tape usage and handle drive cleaning cycles.
-++++ Date: November 11, 2005
-++++ Origin: Arno Lehmann <al at its-lehmann dot de>
-++++ Status:
-++++
-++++ What: Make Bacula manage tape life cycle information and drive
-++++ cleaning cycles.
-++++
-++++ Why: Both parts of this project are important when operating backups.
-++++ We need to know which tapes need replacement, and we need to
-++++ make sure the drives are cleaned when necessary. While many
-++++ tape libraries and even autoloaders can handle all this
-++++ automatically, support by Bacula can be helpful for smaller
-++++ (older) libraries and single drives. Also, checking drive
-++++ status during operation can prevent some failures (as I had to
-++++ learn the hard way...)
-++++
-++++ Notes: First, Bacula could (and even does, to some limited extent)
-++++ record tape and drive usage. For tapes, the number of mounts,
-++++ the amount of data, and the time the tape has actually been
-++++ running could be recorded. Data fields for Read and Write time
-++++ and Nmber of mounts already exist in the catalog (I'm not sure
-++++ if VolBytes is the sum of all bytes ever written to that volume
-++++ by Bacula). This information can be important when determining
-++++ which media to replace. For the tape drives known to Bacula,
-++++ similar information is interesting to determine the device
-++++ status and expected life time: Time it's been Reading and
-++++ Writing, number of tape Loads / Unloads / Errors. This
-++++ information is not yet recorded as far as I know.
-++++
-++++ The next step would be implementing drive cleaning setup.
-++++ Bacula already has knowledge about cleaning tapes. Once it has
-++++ some information about cleaning cycles (measured in drive run
-++++ time, number of tapes used, or calender days, for example) it
-++++ can automatically execute tape cleaning (with an autochanger,
-++++ obviously) or ask for operator assistence loading a cleaning
-++++ tape.
-++++
-++++ The next step would be to implement TAPEALERT checks not only
-++++ when changing tapes and only sending he information to the
-++++ administrator, but rather checking after each tape error,
-++++ checking on a regular basis (for example after each tape file),
-++++ and also before unloading and after loading a new tape. Then,
-++++ depending on the drives TAPEALERT state and the know drive
-++++ cleaning state Bacula could automatically schedule later
-++++ cleaning, clean immediately, or inform the operator.
-++++
-++++ Implementing this would perhaps require another catalog change
-++++ and perhaps major changes in SD code and the DIR-SD protocoll,
-++++ so I'd only consider this worth implementing if it would
-++++ actually be used or even needed by many people.
-++++
-++++Item 14: Merging of multiple backups into a single one. (Also called Synthetic
-++++ Backup or Consolidation).
-++++
-++++ Origin: Marc Cousin and Eric Bollengier
-++++ Date: 15 November 2005
-++++ Status: Depends on first implementing project Item 1 (Migration).
-++++
-++++ What: A merged backup is a backup made without connecting to the Client.
-++++ It would be a Merge of existing backups into a single backup.
-++++ In effect, it is like a restore but to the backup medium.
-++++
-++++ For instance, say that last sunday we made a full backup. Then
-++++ all week long, we created incremental backups, in order to do
-++++ them fast. Now comes sunday again, and we need another full.
-++++ The merged backup makes it possible to do instead an incremental
-++++ backup (during the night for instance), and then create a merged
-++++ backup during the day, by using the full and incrementals from
-++++ the week. The merged backup will be exactly like a full made
-++++ sunday night on the tape, but the production interruption on the
-++++ Client will be minimal, as the Client will only have to send
-++++ incrementals.
-++++
-++++ In fact, if it's done correctly, you could merge all the
-++++ Incrementals into single Incremental, or all the Incrementals
-++++ and the last Differential into a new Differential, or the Full,
-++++ last differential and all the Incrementals into a new Full
-++++ backup. And there is no need to involve the Client.
-++++
-++++ Why: The benefit is that :
-++++ - the Client just does an incremental ;
-++++ - the merged backup on tape is just as a single full backup,
-++++ and can be restored very fast.
-++++
-++++ This is also a way of reducing the backup data since the old
-++++ data can then be pruned (or not) from the catalog, possibly
-++++ allowing older volumes to be recycled
-++++
-++++Item 15: Automatic disabling of devices
-++++ Date: 2005-11-11
-++++ Origin: Peter Eriksson <peter at ifm.liu dot se>
-++++ Status:
-++++
-++++ What: After a configurable amount of fatal errors with a tape drive
-++++ Bacula should automatically disable further use of a certain
-++++ tape drive. There should also be "disable"/"enable" commands in
-++++ the "bconsole" tool.
-++++
-++++ Why: On a multi-drive jukebox there is a possibility of tape drives
-++++ going bad during large backups (needing a cleaning tape run,
-++++ tapes getting stuck). It would be advantageous if Bacula would
-++++ automatically disable further use of a problematic tape drive
-++++ after a configurable amount of errors has occured.
-++++
-++++ An example: I have a multi-drive jukebox (6 drives, 380+ slots)
-++++ where tapes occasionally get stuck inside the drive. Bacula will
-++++ notice that the "mtx-changer" command will fail and then fail
-++++ any backup jobs trying to use that drive. However, it will still
-++++ keep on trying to run new jobs using that drive and fail -
-++++ forever, and thus failing lots and lots of jobs... Since we have
-++++ many drives Bacula could have just automatically disabled
-++++ further use of that drive and used one of the other ones
-++++ instead.
-++++
-++++
-++++Item 16: Directive/mode to backup only file changes, not entire file
-++++ Date: 11 November 2005
-++++ Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
-++++ Marek Bajon <mbajon at bimsplus dot com dot pl>
-++++ Status: RFC
-++++
-++++ What: Currently when a file changes, the entire file will be backed up in
-++++ the next incremental or full backup. To save space on the tapes
-++++ it would be nice to have a mode whereby only the changes to the
-++++ file would be backed up when it is changed.
-++++
-++++ Why: This would save lots of space when backing up large files such as
-++++ logs, mbox files, Outlook PST files and the like.
-++++
-++++ Notes: This would require the usage of disk-based volumes as comparing
-++++ files would not be feasible using a tape drive.
-++++
-++++Item 17: Quick release of FD-SD connection
-++++ Origin: Frank Volf (frank at deze dot org)
-++++ Date: 17 november 2005
-++++ Status:
-++++
-++++ What: In the bacula implementation a backup is finished after all data
-++++ and attributes are succesfully written to storage. When using a
-++++ tape backup it is very annoying that a backup can take a day,
-++++ simply because the current tape (or whatever) is full and the
-++++ administrator has not put a new one in. During that time the
-++++ system cannot be taken off-line, because there is still an open
-++++ session between the storage daemon and the file daemon on the
-++++ client.
-++++
-++++ Although this is a very good strategey for making "safe backups"
-++++ This can be annoying for e.g. laptops, that must remain
-++++ connected until the bacukp is completed.
-++++
-++++ Using a new feature called "migration" it will be possible to
-++++ spool first to harddisk (using a special 'spool' migration
-++++ scheme) and then migrate the backup to tape.
-++++
-++++ There is still the problem of getting the attributes committed.
-++++ If it takes a very long time to do, with the current code, the
-++++ job has not terminated, and the File daemon is not freed up. The
-++++ Storage daemon should release the File daemon as soon as all the
-++++ file data and all the attributes have been sent to it (the SD).
-++++ Currently the SD waits until everything is on tape and all the
-++++ attributes are transmitted to the Director before signalling
-++++ completion to the FD. I don't think I would have any problem
-++++ changing this. The reason is that even if the FD reports back to
-++++ the Dir that all is OK, the job will not terminate until the SD
-++++ has done the same thing -- so in a way keeping the SD-FD link
-++++ open to the very end is not really very productive ...
-+++
-++++ Why: Makes backup of laptops much easier.
-+++
-+++
-+++ ============= Empty RFC form ===========
-+++@@ -245,33 +413,4 @@
-+++ ============== End RFC form ==============
-+++
-+++
-+++-Items completed for release 1.38.0:
-+++-#4 Embedded Python Scripting (implemented in all Daemons)
-+++-#5 Events that call a Python program (Implemented in all
-+++- daemons, but more cleanup work to be done).
-+++-#6 Select one from among Multiple Storage Devices for Job.
-+++- This is already implemented in 1.37.
-+++-#7 Single Job Writing to Multiple Storage Devices. This is
-+++- currently implemented with a Clone feature.
-+++-#- Full multiple drive Autochanger support (done in 1.37)
-+++-#- Built in support for communications encryption (TLS)
-+++- done by Landon Fuller.
-+++-# Support for Unicode characters
-+++- (via UTF-8) on Win32 machines thanks to Thorsten Engel.
-+++-Item 8: Break the one-to-one Relationship between a Job and a
-+++- Specific Storage Device (or Devices if #10 is implemented).
-+++-
-+++-Completed items from last year's list:
-+++-Item 1: Multiple simultaneous Jobs. (done)
-+++-Item 3: Write the bscan program -- also write a bcopy program (done).
-+++-Item 5: Implement Label templates (done).
-+++-Item 6: Write a regression script (done)
-+++-Item 9: Add SSL to daemon communications (done by Landon Fuller)
-+++-Item 10: Define definitive tape format (done)
-+++-Item 3: GUI for interactive restore. Partially Implemented in 1.34
-+++- Note, there is now a complete Webmin plugin, a partial
-+++- GNOME console, and an excellent wx-console GUI.
-+++-Item 4: GUI for interactive backup
-+++-Item 2: Job Data Spooling.
-+++- Done: Regular expression matching.
-+++-Item 10: New daemon communication protocol (this has been dropped).
-++++Items completed for release 1.38.0 -- see kernsdone
-+++Index: patches/1.38.1-to-1.38.2.patch
-+++===================================================================
-+++RCS file: patches/1.38.1-to-1.38.2.patch
-+++diff -N patches/1.38.1-to-1.38.2.patch
-+++--- /dev/null 1 Jan 1970 00:00:00 -0000
-++++++ patches/1.38.1-to-1.38.2.patch 21 Nov 2005 18:19:05 -0000
-+++@@ -0,0 +1,3528 @@
-++++
-++++ This patch fixes the following bugs:
-++++
-++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++++ says that this patch does not fix his problem)
-++++- Fix cancel failure bug. Bug #481
-++++- Fix failure when Pool name has spaces. Bug #487
-++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++- Fix a couple of free()s in src/filed/acl.c
-++++- Fix memory overrun in bfile.c in building OS X resource
-++++ fork filename. Bug #489
-++++
-++++This patch is applied to Bacula source version 1.38.1 and will
-++++produce Bacula source version 1.38.2. Apply it with:
-++++
-++++ cd <bacula-1.38.1-source>
-++++ ./configure (your options) if not already done
-++++ patch -p0 <1.38.1-to-1.38.2.patch
-++++ make
-++++ make install
-++++
-++++? osx_finder.patch
-++++Index: ChangeLog
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/ChangeLog,v
-++++retrieving revision 1.154.2.7
-++++diff -u -r1.154.2.7 ChangeLog
-++++--- ChangeLog 15 Nov 2005 09:27:19 -0000 1.154.2.7
-+++++++ ChangeLog 21 Nov 2005 13:17:56 -0000
-++++@@ -1,4 +1,14 @@
-++++
-+++++Changes to 1.38.2:
-+++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++- Fix bnet-server bug found on OpenBSD. Bug #486
-+++++- Fix cancel failure bug. Bug #481
-+++++- Fix failure when Pool name has spaces. Bug #487
-+++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++- Fix a couple of free()s in src/filed/acl.c
-+++++- Fix memory overrun in bfile.c in building OS X resource
-+++++ fork filename. Bug #489
-+++++- Add Pool name to SD status output.
-++++
-++++ Changes to 1.38.1:
-++++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-++++Index: ReleaseNotes
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/ReleaseNotes,v
-++++retrieving revision 1.147.2.9
-++++diff -u -r1.147.2.9 ReleaseNotes
-++++--- ReleaseNotes 15 Nov 2005 09:27:19 -0000 1.147.2.9
-+++++++ ReleaseNotes 21 Nov 2005 13:17:57 -0000
-++++@@ -1,10 +1,21 @@
-++++
-++++- Release Notes for Bacula 1.38.1
-+++++ Release Notes for Bacula 1.38.2
-++++
-++++ Bacula code: Total files = 420 Total lines = 138,440 (*.h *.c *.in)
-++++ 20,440 additional lines of code since version 1.36.3
-++++
-++++-Changes since 1.38.0:
-+++++Changes to 1.38.2:
-+++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++- Fix bnet-server bug found on OpenBSD. Bug #486
-+++++- Fix cancel failure bug. Bug #481
-+++++- Fix failure when Pool name has spaces. Bug #487
-+++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++- Fix a couple of free()s in src/filed/acl.c
-+++++- Fix memory overrun in bfile.c in building OS X resource
-+++++ fork filename. Bug #489
-+++++- Add Pool name to SD status output.
-+++++
-+++++Changes to 1.38.1:
-++++ - Corrected ACL for Solaris (David Duchscher and Attila Fulop).
-++++ - Add bacula_mail_summary.sh to examples directory. It makes
-++++ a single email summary of any number of jobs. Submitted
-++++Index: kernstodo
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/kernstodo,v
-++++retrieving revision 1.570.2.6
-++++diff -u -r1.570.2.6 kernstodo
-++++--- kernstodo 4 Nov 2005 09:16:49 -0000 1.570.2.6
-+++++++ kernstodo 21 Nov 2005 13:17:57 -0000
-++++@@ -1,5 +1,5 @@
-++++ Kern's ToDo List
-++++- 03 November 2005
-+++++ 21 November 2005
-++++
-++++ Major development:
-++++ Project Developer
-++++@@ -7,8 +7,6 @@
-++++ Version 1.37 Kern (see below)
-++++ ========================================================
-++++
-++++-Final items for 1.37 before release:
-++++-
-++++ Document:
-++++ - Does ClientRunAfterJob fail the job on a bad return code?
-++++ - Document cleaning up the spool files:
-++++@@ -18,6 +16,8 @@
-++++ - Does WildFile match against full name? Doc.
-++++
-++++ For 1.39:
-+++++- Make sure that all do_prompt() calls in Dir check for
-+++++ -1 (error) and -2 (cancel) returns.
-++++ - Look at -D_FORTIFY_SOURCE=2
-++++ - Add Win32 FileSet definition somewhere
-++++ - Look at fixing restore status stats in SD.
-++++@@ -27,6 +27,12 @@
-++++ encountered, read many times (as it currently does), and if the
-++++ block cannot be read, skip to the next block, and try again. If
-++++ that fails, skip to the next file and try again, ...
-+++++- Add level table:
-+++++ create table LevelType (LevelType binary(1), LevelTypeLong tinyblob);
-+++++ insert into LevelType (LevelType,LevelTypeLong) values
-+++++ ("F","Full"),
-+++++ ("D","Diff"),
-+++++ ("I","Inc");
-++++ - Add ACL to restore only to original location.
-++++ - Add a recursive mark command (rmark) to restore.
-++++ - "Minimum Job Interval = nnn" sets minimum interval between Jobs
-++++@@ -1246,219 +1252,4 @@
-++++ ====
-++++
-++++
-++++-=== Done
-++++-- Save mount point for directories not traversed with onefs=yes.
-++++-- Add seconds to start and end times in the Job report output.
-++++-- if 2 concurrent backups are attempted on the same tape
-++++- drive (autoloader) into different tape pools, one of them will exit
-++++- fatally instead of halting until the drive is idle
-++++-- Update StartTime if job held in Job Queue.
-++++-- Look at www.nu2.nu/pebuilder as a helper for full windows
-++++- bare metal restore. (done by Scott)
-++++-- Fix orphanned buffers:
-++++- Orphaned buffer: 24 bytes allocated at line 808 of rufus-dir job.c
-++++- Orphaned buffer: 40 bytes allocated at line 45 of rufus-dir alist.c
-++++-- Implement Preben's suggestion to add
-++++- File System Types = ext2, ext3
-++++- to FileSets, thus simplifying backup of *all* local partitions.
-++++-- Try to open a device on each Job if it was not opened
-++++- when the SD started.
-++++-- Add dump of VolSessionId/Time and FileIndex with bls.
-++++-- If Bacula does not find the right tape in the Autochanger,
-++++- then mark the tape in error and move on rather than asking
-++++- for operator intervention.
-++++-- Cancel command should include JobId in list of Jobs.
-++++-- Add performance testing hooks
-++++-- Bootstrap from JobMedia records.
-++++-- Implement WildFile and WildDir to solve problem of
-++++- saving only *.doc files.
-++++-- Fix
-++++- Please use the "label" command to create a new Volume for:
-++++- Storage: DDS-4-changer
-++++- Media type:
-++++- Pool: Default
-++++- label
-++++- The defined Storage resources are:
-++++-- Copy Changer Device and Changer Command from Autochanger
-++++- to Device resource in SD if none given in Device resource.
-++++-- 1. Automatic use of more than one drive in an autochanger (done)
-++++-- 2. Automatic selection of the correct drive for each Job (i.e.
-++++- selects a drive with an appropriate Volume for the Job) (done)
-++++-- 6. Allow multiple simultaneous Jobs referencing the same pool write
-++++- to several tapes (some new directive(s) are are probably needed for
-++++- this) (done)
-++++-- Locking (done)
-++++-- Key on Storage rather than Pool (done)
-++++-- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
-++++-- Synchronize multiple drives so that not more
-++++- than one loads a tape and any time (done)
-++++-- 4. Use Changer Device and Changer Command specified in the
-++++- Autochanger resource, if none is found in the Device resource.
-++++- You can continue to specify them in the Device resource if you want
-++++- or need them to be different for each device.
-++++-- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
-++++- that can allow a Device be part of an Autochanger, and hence the changer
-++++- script protected, but if set to no, will prevent the Device from being
-++++- automatically selected from the changer. This allows the device to
-++++- be directly accessed through its Device name, but not through the
-++++- AutoChanger name.
-++++-#6 Select one from among Multiple Storage Devices for Job
-++++-#5 Events that call a Python program
-++++- (Implemented in Dir/SD)
-++++-- Make sure the Device name is in the Query packet returned.
-++++-- Don't start a second file job if one is already running.
-++++-- Implement EOF/EOV labels for ANSI labels
-++++-- Implement IBM labels.
-++++-- When Python creates a new label, the tape is immediately
-++++- recycled and no label created. This happens when using
-++++- autolabeling -- even when Python doesn't generate the name.
-++++-- Scratch Pool where the volumes can be re-assigned to any Pool.
-++++-- 28-Mar 23:19 rufus-sd: acquire.c:379 Device "DDS-4" (/dev/nst0)
-++++- is busy reading. Job 6 canceled.
-++++-- Remove separate thread for opening devices in SD. On the other
-++++- hand, don't block waiting for open() for devices.
-++++-- Fix code to either handle updating NumVol or to calculate it in
-++++- Dir next_vol.c
-++++-- Ensure that you cannot exclude a directory or a file explicitly
-++++- Included with File.
-++++-#4 Embedded Python Scripting
-++++- (Implemented in Dir/SD/FD)
-++++-- Add Python writable variable for changing the Priority,
-++++- Client, Storage, JobStatus (error), ...
-++++-- SD Python
-++++- - Solicit Events
-++++-- Add disk seeking on restore; turn off seek on tapes.
-++++- stored/match_bsr.c
-++++-- Look at dird_conf.c:1000: warning: `int size'
-++++- might be used uninitialized in this function
-++++-- Indicate when a Job is purged/pruned during restore.
-++++-- Implement some way to turn off automatic pruning in Jobs.
-++++-- Implement a way an Admin Job can prune, possibly multiple
-++++- clients -- Python script?
-++++-- Look at Preben's acl.c error handling code.
-++++-- SD crashes after a tape restore then doing a backup.
-++++-- If drive is opened read/write, close it and re-open
-++++- read-only if doing a restore, and vice-versa.
-++++-- Windows restore:
-++++- data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
-++++- > ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
-++++- > Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen
-++++- > Prozess verwendet wird.
-++++- Restore restores all files, but then fails at the end trying
-++++- to set the attributes of e:
-++++- from failed jobs.- Resolve the problem between Device name and Archive name,
-++++- and fix SD messages.
-++++-- Tell the "restore" user when browsing is no longer possible.
-++++-- Add a restore directory-x
-++++-- Write non-optimized bsrs from the JobMedia and Media records,
-++++- even after Files are pruned.
-++++-- Delete Stripe and Copy from VolParams to save space.
-++++-- Fix option 2 of restore -- list where file is backed up -- require Client,
-++++- then list last 20 backups.
-++++-- Finish implementation of passing all Storage and Device needs to
-++++- the SD.
-++++-- Move test for max wait time exceeded in job.c up -- Peter's idea.
-++++-## Consider moving docs to their own project.
-++++-## Move rescue to its own project.
-++++-- Add client version to the Client name line that prints in
-++++- the Job report.
-++++-- Fix the Rescue CDROM.
-++++-- By the way: on page http://www.bacula.org/?page=tapedrives , at the
-++++- bottom, the link to "Tape Testing Chapter" is broken. It goes to
-++++- /html-manual/... while the others point to /rel-manual/...
-++++-- Device resource needs the "name" of the SD.
-++++-- Specify a single directory to restore.
-++++-- Implement MediaType keyword in bsr?
-++++-- Add a date and time stamp at the beginning of every line in the
-++++- Job report (Volker Sauer).
-++++-- Add level to estimate command.
-++++-- Add "limit=n" for "list jobs"
-++++-- Make bootstrap filename unique.
-++++-- Make Dmsg look at global before calling subroutine.
-++++-- From Chris Hull:
-++++- it seems to be complaining about 12:00pm which should be a valid 12
-++++- hour time. I changed the time to 11:59am and everything works fine.
-++++- Also 12:00am works fine. 0:00pm also works (which I don't think
-++++- should). None of the values 12:00pm - 12:59pm work for that matter.
-++++-- Require restore via the restore command or make a restore Job
-++++- get the bootstrap file.
-++++-- Implement Maximum Job Spool Size
-++++-- Fix 3993 error in SD. It forgets to look at autochanger
-++++- resource for device command, ...
-++++-- 3. Prevent two drives requesting the same Volume in any given
-++++- autochanger, by checking if a Volume is mounted on another drive
-++++- in an Autochanger.
-++++-- Upgrade to MySQL 4.1.12 See:
-++++- http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
-++++-- Add # Job Level date to bsr file
-++++-- Implement "PreferMountedVolumes = yes|no" in Job resource.
-++++-## Integrate web-bacula into a new Bacula project with
-++++- bimagemgr.
-++++-- Cleaning tapes should have Status "Cleaning" rather than append.
-++++-- Make sure that Python has access to Client address/port so that
-++++- it can check if Clients are alive.
-++++-- Review all items in "restore".
-++++-- Fix PostgreSQL GROUP BY problems in restore.
-++++-- Fix PostgreSQL sql problems in bugs.
-++++-- After rename
-++++- 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume
-++++- "DLT-13Feb04".
-++++- Current Volume "DLT-04Jul05" not acceptable because:
-++++- 1997 Volume "DLT-13Feb04" not in catalog.
-++++- 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device
-++++- "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
-++++-## Create a new GUI chapter explaining all the GUI programs.
-++++-- Make "update slots" when pointing to Autochanger, remove
-++++- all Volumes from other drives. "update slots all-drives"?
-++++- No, this is done by modifying mtx-changer to list what is
-++++- in the drives.
-++++-- Finish TLS implementation.
-++++-- Port limiting -m in iptables to prevent DoS attacks
-++++- could cause broken pipes on Bacula.
-++++-6. Build and test the Volume Shadow Copy (VSS) for Win32.
-++++-- Allow cancel of unknown Job
-++++-- State not saved when closing Win32 FD by icon
-++++-- bsr-opt-test fails. bsr deleted. Fix.
-++++-- Move Python daemon variables from Job to Bacula object.
-++++- WorkingDir, ConfigFile
-++++-- Document that Bootstrap files can be written with cataloging
-++++- turned off.
-++++-- Document details of ANSI/IBM labels
-++++-- OS linux 2.4
-++++- 1) ADIC, DLT, FastStor 4000, 7*20GB
-++++-- Linux Sony LIB-D81, AIT-3 library works.
-++++-- Doc the following
-++++- to activate, check or disable the hardware compression feature on my
-++++- exb-8900 i use the exabyte "MammothTool" you can get it here:
-++++- http://www.exabyte.com/support/online/downloads/index.cfm
-++++- There is a solaris version of this tool. With option -C 0 or 1 you can
-++++- disable or activate compression. Start this tool without any options for
-++++- a small reference.
-++++-- Document Heartbeat Interval in the dealing with firewalls section.
-++++-- Document new CDROM directory.
-++++-- On Win32 working directory must have drive letter ????
-++++-- On Win32 working directory must be writable by SYSTEM to
-++++- do restores.
-++++-- Document that ChangerDevice is used for Alert command.
-++++-- Add better documentation on how restores can be done
-++++-8. Take one more try at making DVD writing work (no go)
-++++-7. Write a bacula-web document
-++++-- Why isn't the DEVICE structure defined when doing
-++++- a reservation?
-++++-- Multi-drive changer seems to only use drive 0
-++++- Multiple drives don't seem to be opened.
-++++-- My database is growing
-++++-- Call GetLastError() in the berrno constructor rather
-++++- than delaying until strerror.
-++++-- Tape xxx in drive 0, requested in drive 1
-++++-- The mount command does not work with drives other than 0.
-++++-- A mount should cause the SD to re-examine what Slot is
-++++- loaded.
-++++-- The SD locks on to the first available drive then
-++++- wants a Volume that is released but in another drive --
-++++- chaos.
-++++-- Run the regression scripts on Solaris and FreeBSD
-++++-- Figure out how to package gui, and rescue programs.
-++++-- Add a .dir command to restore tree code to eliminate the problem
-++++-- Mount after manually unloading changer causes hang in SD
-++++-- Fix JobACL with restore by JobId.
-+++++=== Done -- see kernsdone
-++++Index: kes-1.38
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-++++retrieving revision 1.1.2.13
-++++diff -u -r1.1.2.13 kes-1.38
-++++--- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-+++++++ kes-1.38 21 Nov 2005 13:17:57 -0000
-++++@@ -3,6 +3,18 @@
-++++
-++++ General:
-++++
-+++++Changes to 1.38.2:
-+++++20Oct05
-+++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++- Fix bnet-server bug found on OpenBSD. Bug #486
-+++++- Fix cancel failure bug. Bug #481
-+++++- Fix failure when Pool name has spaces. Bug #487
-+++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++- Fix a couple of free()s in src/filed/acl.c
-+++++- Fix memory overrun in bfile.c in building OS X resource
-+++++ fork filename. Bug #489
-+++++- Add Pool name to SD status output.
-+++++
-++++ Changes to 1.38.1:
-++++ 14Oct05
-++++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-++++Index: projects
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/projects,v
-++++retrieving revision 1.12.2.3
-++++diff -u -r1.12.2.3 projects
-++++--- projects 10 Nov 2005 20:25:27 -0000 1.12.2.3
-+++++++ projects 21 Nov 2005 13:17:58 -0000
-++++@@ -228,7 +228,175 @@
-++++
-++++ Why: Performance enhancement.
-++++
-+++++Item 13: Let Bacula log tape usage and handle drive cleaning cycles.
-+++++ Date: November 11, 2005
-+++++ Origin: Arno Lehmann <al at its-lehmann dot de>
-+++++ Status:
-+++++
-+++++ What: Make Bacula manage tape life cycle information and drive
-+++++ cleaning cycles.
-+++++
-+++++ Why: Both parts of this project are important when operating backups.
-+++++ We need to know which tapes need replacement, and we need to
-+++++ make sure the drives are cleaned when necessary. While many
-+++++ tape libraries and even autoloaders can handle all this
-+++++ automatically, support by Bacula can be helpful for smaller
-+++++ (older) libraries and single drives. Also, checking drive
-+++++ status during operation can prevent some failures (as I had to
-+++++ learn the hard way...)
-+++++
-+++++ Notes: First, Bacula could (and even does, to some limited extent)
-+++++ record tape and drive usage. For tapes, the number of mounts,
-+++++ the amount of data, and the time the tape has actually been
-+++++ running could be recorded. Data fields for Read and Write time
-+++++ and Nmber of mounts already exist in the catalog (I'm not sure
-+++++ if VolBytes is the sum of all bytes ever written to that volume
-+++++ by Bacula). This information can be important when determining
-+++++ which media to replace. For the tape drives known to Bacula,
-+++++ similar information is interesting to determine the device
-+++++ status and expected life time: Time it's been Reading and
-+++++ Writing, number of tape Loads / Unloads / Errors. This
-+++++ information is not yet recorded as far as I know.
-+++++
-+++++ The next step would be implementing drive cleaning setup.
-+++++ Bacula already has knowledge about cleaning tapes. Once it has
-+++++ some information about cleaning cycles (measured in drive run
-+++++ time, number of tapes used, or calender days, for example) it
-+++++ can automatically execute tape cleaning (with an autochanger,
-+++++ obviously) or ask for operator assistence loading a cleaning
-+++++ tape.
-+++++
-+++++ The next step would be to implement TAPEALERT checks not only
-+++++ when changing tapes and only sending he information to the
-+++++ administrator, but rather checking after each tape error,
-+++++ checking on a regular basis (for example after each tape file),
-+++++ and also before unloading and after loading a new tape. Then,
-+++++ depending on the drives TAPEALERT state and the know drive
-+++++ cleaning state Bacula could automatically schedule later
-+++++ cleaning, clean immediately, or inform the operator.
-+++++
-+++++ Implementing this would perhaps require another catalog change
-+++++ and perhaps major changes in SD code and the DIR-SD protocoll,
-+++++ so I'd only consider this worth implementing if it would
-+++++ actually be used or even needed by many people.
-+++++
-+++++Item 14: Merging of multiple backups into a single one. (Also called Synthetic
-+++++ Backup or Consolidation).
-+++++
-+++++ Origin: Marc Cousin and Eric Bollengier
-+++++ Date: 15 November 2005
-+++++ Status: Depends on first implementing project Item 1 (Migration).
-+++++
-+++++ What: A merged backup is a backup made without connecting to the Client.
-+++++ It would be a Merge of existing backups into a single backup.
-+++++ In effect, it is like a restore but to the backup medium.
-+++++
-+++++ For instance, say that last sunday we made a full backup. Then
-+++++ all week long, we created incremental backups, in order to do
-+++++ them fast. Now comes sunday again, and we need another full.
-+++++ The merged backup makes it possible to do instead an incremental
-+++++ backup (during the night for instance), and then create a merged
-+++++ backup during the day, by using the full and incrementals from
-+++++ the week. The merged backup will be exactly like a full made
-+++++ sunday night on the tape, but the production interruption on the
-+++++ Client will be minimal, as the Client will only have to send
-+++++ incrementals.
-+++++
-+++++ In fact, if it's done correctly, you could merge all the
-+++++ Incrementals into single Incremental, or all the Incrementals
-+++++ and the last Differential into a new Differential, or the Full,
-+++++ last differential and all the Incrementals into a new Full
-+++++ backup. And there is no need to involve the Client.
-+++++
-+++++ Why: The benefit is that :
-+++++ - the Client just does an incremental ;
-+++++ - the merged backup on tape is just as a single full backup,
-+++++ and can be restored very fast.
-+++++
-+++++ This is also a way of reducing the backup data since the old
-+++++ data can then be pruned (or not) from the catalog, possibly
-+++++ allowing older volumes to be recycled
-+++++
-+++++Item 15: Automatic disabling of devices
-+++++ Date: 2005-11-11
-+++++ Origin: Peter Eriksson <peter at ifm.liu dot se>
-+++++ Status:
-+++++
-+++++ What: After a configurable amount of fatal errors with a tape drive
-+++++ Bacula should automatically disable further use of a certain
-+++++ tape drive. There should also be "disable"/"enable" commands in
-+++++ the "bconsole" tool.
-+++++
-+++++ Why: On a multi-drive jukebox there is a possibility of tape drives
-+++++ going bad during large backups (needing a cleaning tape run,
-+++++ tapes getting stuck). It would be advantageous if Bacula would
-+++++ automatically disable further use of a problematic tape drive
-+++++ after a configurable amount of errors has occured.
-+++++
-+++++ An example: I have a multi-drive jukebox (6 drives, 380+ slots)
-+++++ where tapes occasionally get stuck inside the drive. Bacula will
-+++++ notice that the "mtx-changer" command will fail and then fail
-+++++ any backup jobs trying to use that drive. However, it will still
-+++++ keep on trying to run new jobs using that drive and fail -
-+++++ forever, and thus failing lots and lots of jobs... Since we have
-+++++ many drives Bacula could have just automatically disabled
-+++++ further use of that drive and used one of the other ones
-+++++ instead.
-+++++
-+++++
-+++++Item 16: Directive/mode to backup only file changes, not entire file
-+++++ Date: 11 November 2005
-+++++ Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
-+++++ Marek Bajon <mbajon at bimsplus dot com dot pl>
-+++++ Status: RFC
-+++++
-+++++ What: Currently when a file changes, the entire file will be backed up in
-+++++ the next incremental or full backup. To save space on the tapes
-+++++ it would be nice to have a mode whereby only the changes to the
-+++++ file would be backed up when it is changed.
-+++++
-+++++ Why: This would save lots of space when backing up large files such as
-+++++ logs, mbox files, Outlook PST files and the like.
-+++++
-+++++ Notes: This would require the usage of disk-based volumes as comparing
-+++++ files would not be feasible using a tape drive.
-+++++
-+++++Item 17: Quick release of FD-SD connection
-+++++ Origin: Frank Volf (frank at deze dot org)
-+++++ Date: 17 november 2005
-+++++ Status:
-+++++
-+++++ What: In the bacula implementation a backup is finished after all data
-+++++ and attributes are succesfully written to storage. When using a
-+++++ tape backup it is very annoying that a backup can take a day,
-+++++ simply because the current tape (or whatever) is full and the
-+++++ administrator has not put a new one in. During that time the
-+++++ system cannot be taken off-line, because there is still an open
-+++++ session between the storage daemon and the file daemon on the
-+++++ client.
-+++++
-+++++ Although this is a very good strategey for making "safe backups"
-+++++ This can be annoying for e.g. laptops, that must remain
-+++++ connected until the bacukp is completed.
-+++++
-+++++ Using a new feature called "migration" it will be possible to
-+++++ spool first to harddisk (using a special 'spool' migration
-+++++ scheme) and then migrate the backup to tape.
-+++++
-+++++ There is still the problem of getting the attributes committed.
-+++++ If it takes a very long time to do, with the current code, the
-+++++ job has not terminated, and the File daemon is not freed up. The
-+++++ Storage daemon should release the File daemon as soon as all the
-+++++ file data and all the attributes have been sent to it (the SD).
-+++++ Currently the SD waits until everything is on tape and all the
-+++++ attributes are transmitted to the Director before signalling
-+++++ completion to the FD. I don't think I would have any problem
-+++++ changing this. The reason is that even if the FD reports back to
-+++++ the Dir that all is OK, the job will not terminate until the SD
-+++++ has done the same thing -- so in a way keeping the SD-FD link
-+++++ open to the very end is not really very productive ...
-++++
-+++++ Why: Makes backup of laptops much easier.
-++++
-++++
-++++ ============= Empty RFC form ===========
-++++@@ -245,33 +413,4 @@
-++++ ============== End RFC form ==============
-++++
-++++
-++++-Items completed for release 1.38.0:
-++++-#4 Embedded Python Scripting (implemented in all Daemons)
-++++-#5 Events that call a Python program (Implemented in all
-++++- daemons, but more cleanup work to be done).
-++++-#6 Select one from among Multiple Storage Devices for Job.
-++++- This is already implemented in 1.37.
-++++-#7 Single Job Writing to Multiple Storage Devices. This is
-++++- currently implemented with a Clone feature.
-++++-#- Full multiple drive Autochanger support (done in 1.37)
-++++-#- Built in support for communications encryption (TLS)
-++++- done by Landon Fuller.
-++++-# Support for Unicode characters
-++++- (via UTF-8) on Win32 machines thanks to Thorsten Engel.
-++++-Item 8: Break the one-to-one Relationship between a Job and a
-++++- Specific Storage Device (or Devices if #10 is implemented).
-++++-
-++++-Completed items from last year's list:
-++++-Item 1: Multiple simultaneous Jobs. (done)
-++++-Item 3: Write the bscan program -- also write a bcopy program (done).
-++++-Item 5: Implement Label templates (done).
-++++-Item 6: Write a regression script (done)
-++++-Item 9: Add SSL to daemon communications (done by Landon Fuller)
-++++-Item 10: Define definitive tape format (done)
-++++-Item 3: GUI for interactive restore. Partially Implemented in 1.34
-++++- Note, there is now a complete Webmin plugin, a partial
-++++- GNOME console, and an excellent wx-console GUI.
-++++-Item 4: GUI for interactive backup
-++++-Item 2: Job Data Spooling.
-++++- Done: Regular expression matching.
-++++-Item 10: New daemon communication protocol (this has been dropped).
-+++++Items completed for release 1.38.0 -- see kernsdone
-++++Index: patches/1.38.1-to-1.38.2.patch
-++++===================================================================
-++++RCS file: patches/1.38.1-to-1.38.2.patch
-++++diff -N patches/1.38.1-to-1.38.2.patch
-++++--- /dev/null 1 Jan 1970 00:00:00 -0000
-+++++++ patches/1.38.1-to-1.38.2.patch 21 Nov 2005 13:17:58 -0000
-++++@@ -0,0 +1,2471 @@
-+++++
-+++++ This patch fixes the following bugs:
-+++++
-+++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+++++ says that this patch does not fix his problem)
-+++++- Fix cancel failure bug. Bug #481
-+++++- Fix failure when Pool name has spaces. Bug #487
-+++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++- Fix a couple of free()s in src/filed/acl.c
-+++++- Fix memory overrun in bfile.c in building OS X resource
-+++++ fork filename. Bug #489
-+++++
-+++++This patch is applied to Bacula source version 1.38.1 and will
-+++++produce Bacula source version 1.38.2. Apply it with:
-+++++
-+++++ cd <bacula-1.38.1-source>
-+++++ ./configure (your options) if not already done
-+++++ patch -p0 <1.38.1-to-1.38.2.patch
-+++++ make
-+++++ make install
-+++++
-+++++? osx_finder.patch
-+++++Index: ChangeLog
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/ChangeLog,v
-+++++retrieving revision 1.154.2.7
-+++++diff -u -r1.154.2.7 ChangeLog
-+++++--- ChangeLog 15 Nov 2005 09:27:19 -0000 1.154.2.7
-++++++++ ChangeLog 21 Nov 2005 13:12:58 -0000
-+++++@@ -1,4 +1,14 @@
-+++++
-++++++Changes to 1.38.2:
-++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++++- Fix bnet-server bug found on OpenBSD. Bug #486
-++++++- Fix cancel failure bug. Bug #481
-++++++- Fix failure when Pool name has spaces. Bug #487
-++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++++- Fix a couple of free()s in src/filed/acl.c
-++++++- Fix memory overrun in bfile.c in building OS X resource
-++++++ fork filename. Bug #489
-++++++- Add Pool name to SD status output.
-+++++
-+++++ Changes to 1.38.1:
-+++++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-+++++Index: ReleaseNotes
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/ReleaseNotes,v
-+++++retrieving revision 1.147.2.9
-+++++diff -u -r1.147.2.9 ReleaseNotes
-+++++--- ReleaseNotes 15 Nov 2005 09:27:19 -0000 1.147.2.9
-++++++++ ReleaseNotes 21 Nov 2005 13:12:59 -0000
-+++++@@ -1,10 +1,21 @@
-+++++
-+++++- Release Notes for Bacula 1.38.1
-++++++ Release Notes for Bacula 1.38.2
-+++++
-+++++ Bacula code: Total files = 420 Total lines = 138,440 (*.h *.c *.in)
-+++++ 20,440 additional lines of code since version 1.36.3
-+++++
-+++++-Changes since 1.38.0:
-++++++Changes to 1.38.2:
-++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++++- Fix bnet-server bug found on OpenBSD. Bug #486
-++++++- Fix cancel failure bug. Bug #481
-++++++- Fix failure when Pool name has spaces. Bug #487
-++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++++- Fix a couple of free()s in src/filed/acl.c
-++++++- Fix memory overrun in bfile.c in building OS X resource
-++++++ fork filename. Bug #489
-++++++- Add Pool name to SD status output.
-++++++
-++++++Changes to 1.38.1:
-+++++ - Corrected ACL for Solaris (David Duchscher and Attila Fulop).
-+++++ - Add bacula_mail_summary.sh to examples directory. It makes
-+++++ a single email summary of any number of jobs. Submitted
-+++++Index: kernstodo
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/kernstodo,v
-+++++retrieving revision 1.570.2.6
-+++++diff -u -r1.570.2.6 kernstodo
-+++++--- kernstodo 4 Nov 2005 09:16:49 -0000 1.570.2.6
-++++++++ kernstodo 21 Nov 2005 13:13:00 -0000
-+++++@@ -1,5 +1,5 @@
-+++++ Kern's ToDo List
-+++++- 03 November 2005
-++++++ 21 November 2005
-+++++
-+++++ Major development:
-+++++ Project Developer
-+++++@@ -7,8 +7,6 @@
-+++++ Version 1.37 Kern (see below)
-+++++ ========================================================
-+++++
-+++++-Final items for 1.37 before release:
-+++++-
-+++++ Document:
-+++++ - Does ClientRunAfterJob fail the job on a bad return code?
-+++++ - Document cleaning up the spool files:
-+++++@@ -18,6 +16,8 @@
-+++++ - Does WildFile match against full name? Doc.
-+++++
-+++++ For 1.39:
-++++++- Make sure that all do_prompt() calls in Dir check for
-++++++ -1 (error) and -2 (cancel) returns.
-+++++ - Look at -D_FORTIFY_SOURCE=2
-+++++ - Add Win32 FileSet definition somewhere
-+++++ - Look at fixing restore status stats in SD.
-+++++@@ -27,6 +27,12 @@
-+++++ encountered, read many times (as it currently does), and if the
-+++++ block cannot be read, skip to the next block, and try again. If
-+++++ that fails, skip to the next file and try again, ...
-++++++- Add level table:
-++++++ create table LevelType (LevelType binary(1), LevelTypeLong tinyblob);
-++++++ insert into LevelType (LevelType,LevelTypeLong) values
-++++++ ("F","Full"),
-++++++ ("D","Diff"),
-++++++ ("I","Inc");
-+++++ - Add ACL to restore only to original location.
-+++++ - Add a recursive mark command (rmark) to restore.
-+++++ - "Minimum Job Interval = nnn" sets minimum interval between Jobs
-+++++@@ -1246,219 +1252,4 @@
-+++++ ====
-+++++
-+++++
-+++++-=== Done
-+++++-- Save mount point for directories not traversed with onefs=yes.
-+++++-- Add seconds to start and end times in the Job report output.
-+++++-- if 2 concurrent backups are attempted on the same tape
-+++++- drive (autoloader) into different tape pools, one of them will exit
-+++++- fatally instead of halting until the drive is idle
-+++++-- Update StartTime if job held in Job Queue.
-+++++-- Look at www.nu2.nu/pebuilder as a helper for full windows
-+++++- bare metal restore. (done by Scott)
-+++++-- Fix orphanned buffers:
-+++++- Orphaned buffer: 24 bytes allocated at line 808 of rufus-dir job.c
-+++++- Orphaned buffer: 40 bytes allocated at line 45 of rufus-dir alist.c
-+++++-- Implement Preben's suggestion to add
-+++++- File System Types = ext2, ext3
-+++++- to FileSets, thus simplifying backup of *all* local partitions.
-+++++-- Try to open a device on each Job if it was not opened
-+++++- when the SD started.
-+++++-- Add dump of VolSessionId/Time and FileIndex with bls.
-+++++-- If Bacula does not find the right tape in the Autochanger,
-+++++- then mark the tape in error and move on rather than asking
-+++++- for operator intervention.
-+++++-- Cancel command should include JobId in list of Jobs.
-+++++-- Add performance testing hooks
-+++++-- Bootstrap from JobMedia records.
-+++++-- Implement WildFile and WildDir to solve problem of
-+++++- saving only *.doc files.
-+++++-- Fix
-+++++- Please use the "label" command to create a new Volume for:
-+++++- Storage: DDS-4-changer
-+++++- Media type:
-+++++- Pool: Default
-+++++- label
-+++++- The defined Storage resources are:
-+++++-- Copy Changer Device and Changer Command from Autochanger
-+++++- to Device resource in SD if none given in Device resource.
-+++++-- 1. Automatic use of more than one drive in an autochanger (done)
-+++++-- 2. Automatic selection of the correct drive for each Job (i.e.
-+++++- selects a drive with an appropriate Volume for the Job) (done)
-+++++-- 6. Allow multiple simultaneous Jobs referencing the same pool write
-+++++- to several tapes (some new directive(s) are are probably needed for
-+++++- this) (done)
-+++++-- Locking (done)
-+++++-- Key on Storage rather than Pool (done)
-+++++-- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
-+++++-- Synchronize multiple drives so that not more
-+++++- than one loads a tape and any time (done)
-+++++-- 4. Use Changer Device and Changer Command specified in the
-+++++- Autochanger resource, if none is found in the Device resource.
-+++++- You can continue to specify them in the Device resource if you want
-+++++- or need them to be different for each device.
-+++++-- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
-+++++- that can allow a Device be part of an Autochanger, and hence the changer
-+++++- script protected, but if set to no, will prevent the Device from being
-+++++- automatically selected from the changer. This allows the device to
-+++++- be directly accessed through its Device name, but not through the
-+++++- AutoChanger name.
-+++++-#6 Select one from among Multiple Storage Devices for Job
-+++++-#5 Events that call a Python program
-+++++- (Implemented in Dir/SD)
-+++++-- Make sure the Device name is in the Query packet returned.
-+++++-- Don't start a second file job if one is already running.
-+++++-- Implement EOF/EOV labels for ANSI labels
-+++++-- Implement IBM labels.
-+++++-- When Python creates a new label, the tape is immediately
-+++++- recycled and no label created. This happens when using
-+++++- autolabeling -- even when Python doesn't generate the name.
-+++++-- Scratch Pool where the volumes can be re-assigned to any Pool.
-+++++-- 28-Mar 23:19 rufus-sd: acquire.c:379 Device "DDS-4" (/dev/nst0)
-+++++- is busy reading. Job 6 canceled.
-+++++-- Remove separate thread for opening devices in SD. On the other
-+++++- hand, don't block waiting for open() for devices.
-+++++-- Fix code to either handle updating NumVol or to calculate it in
-+++++- Dir next_vol.c
-+++++-- Ensure that you cannot exclude a directory or a file explicitly
-+++++- Included with File.
-+++++-#4 Embedded Python Scripting
-+++++- (Implemented in Dir/SD/FD)
-+++++-- Add Python writable variable for changing the Priority,
-+++++- Client, Storage, JobStatus (error), ...
-+++++-- SD Python
-+++++- - Solicit Events
-+++++-- Add disk seeking on restore; turn off seek on tapes.
-+++++- stored/match_bsr.c
-+++++-- Look at dird_conf.c:1000: warning: `int size'
-+++++- might be used uninitialized in this function
-+++++-- Indicate when a Job is purged/pruned during restore.
-+++++-- Implement some way to turn off automatic pruning in Jobs.
-+++++-- Implement a way an Admin Job can prune, possibly multiple
-+++++- clients -- Python script?
-+++++-- Look at Preben's acl.c error handling code.
-+++++-- SD crashes after a tape restore then doing a backup.
-+++++-- If drive is opened read/write, close it and re-open
-+++++- read-only if doing a restore, and vice-versa.
-+++++-- Windows restore:
-+++++- data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
-+++++- > ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
-+++++- > Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen
-+++++- > Prozess verwendet wird.
-+++++- Restore restores all files, but then fails at the end trying
-+++++- to set the attributes of e:
-+++++- from failed jobs.- Resolve the problem between Device name and Archive name,
-+++++- and fix SD messages.
-+++++-- Tell the "restore" user when browsing is no longer possible.
-+++++-- Add a restore directory-x
-+++++-- Write non-optimized bsrs from the JobMedia and Media records,
-+++++- even after Files are pruned.
-+++++-- Delete Stripe and Copy from VolParams to save space.
-+++++-- Fix option 2 of restore -- list where file is backed up -- require Client,
-+++++- then list last 20 backups.
-+++++-- Finish implementation of passing all Storage and Device needs to
-+++++- the SD.
-+++++-- Move test for max wait time exceeded in job.c up -- Peter's idea.
-+++++-## Consider moving docs to their own project.
-+++++-## Move rescue to its own project.
-+++++-- Add client version to the Client name line that prints in
-+++++- the Job report.
-+++++-- Fix the Rescue CDROM.
-+++++-- By the way: on page http://www.bacula.org/?page=tapedrives , at the
-+++++- bottom, the link to "Tape Testing Chapter" is broken. It goes to
-+++++- /html-manual/... while the others point to /rel-manual/...
-+++++-- Device resource needs the "name" of the SD.
-+++++-- Specify a single directory to restore.
-+++++-- Implement MediaType keyword in bsr?
-+++++-- Add a date and time stamp at the beginning of every line in the
-+++++- Job report (Volker Sauer).
-+++++-- Add level to estimate command.
-+++++-- Add "limit=n" for "list jobs"
-+++++-- Make bootstrap filename unique.
-+++++-- Make Dmsg look at global before calling subroutine.
-+++++-- From Chris Hull:
-+++++- it seems to be complaining about 12:00pm which should be a valid 12
-+++++- hour time. I changed the time to 11:59am and everything works fine.
-+++++- Also 12:00am works fine. 0:00pm also works (which I don't think
-+++++- should). None of the values 12:00pm - 12:59pm work for that matter.
-+++++-- Require restore via the restore command or make a restore Job
-+++++- get the bootstrap file.
-+++++-- Implement Maximum Job Spool Size
-+++++-- Fix 3993 error in SD. It forgets to look at autochanger
-+++++- resource for device command, ...
-+++++-- 3. Prevent two drives requesting the same Volume in any given
-+++++- autochanger, by checking if a Volume is mounted on another drive
-+++++- in an Autochanger.
-+++++-- Upgrade to MySQL 4.1.12 See:
-+++++- http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
-+++++-- Add # Job Level date to bsr file
-+++++-- Implement "PreferMountedVolumes = yes|no" in Job resource.
-+++++-## Integrate web-bacula into a new Bacula project with
-+++++- bimagemgr.
-+++++-- Cleaning tapes should have Status "Cleaning" rather than append.
-+++++-- Make sure that Python has access to Client address/port so that
-+++++- it can check if Clients are alive.
-+++++-- Review all items in "restore".
-+++++-- Fix PostgreSQL GROUP BY problems in restore.
-+++++-- Fix PostgreSQL sql problems in bugs.
-+++++-- After rename
-+++++- 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume
-+++++- "DLT-13Feb04".
-+++++- Current Volume "DLT-04Jul05" not acceptable because:
-+++++- 1997 Volume "DLT-13Feb04" not in catalog.
-+++++- 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device
-+++++- "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
-+++++-## Create a new GUI chapter explaining all the GUI programs.
-+++++-- Make "update slots" when pointing to Autochanger, remove
-+++++- all Volumes from other drives. "update slots all-drives"?
-+++++- No, this is done by modifying mtx-changer to list what is
-+++++- in the drives.
-+++++-- Finish TLS implementation.
-+++++-- Port limiting -m in iptables to prevent DoS attacks
-+++++- could cause broken pipes on Bacula.
-+++++-6. Build and test the Volume Shadow Copy (VSS) for Win32.
-+++++-- Allow cancel of unknown Job
-+++++-- State not saved when closing Win32 FD by icon
-+++++-- bsr-opt-test fails. bsr deleted. Fix.
-+++++-- Move Python daemon variables from Job to Bacula object.
-+++++- WorkingDir, ConfigFile
-+++++-- Document that Bootstrap files can be written with cataloging
-+++++- turned off.
-+++++-- Document details of ANSI/IBM labels
-+++++-- OS linux 2.4
-+++++- 1) ADIC, DLT, FastStor 4000, 7*20GB
-+++++-- Linux Sony LIB-D81, AIT-3 library works.
-+++++-- Doc the following
-+++++- to activate, check or disable the hardware compression feature on my
-+++++- exb-8900 i use the exabyte "MammothTool" you can get it here:
-+++++- http://www.exabyte.com/support/online/downloads/index.cfm
-+++++- There is a solaris version of this tool. With option -C 0 or 1 you can
-+++++- disable or activate compression. Start this tool without any options for
-+++++- a small reference.
-+++++-- Document Heartbeat Interval in the dealing with firewalls section.
-+++++-- Document new CDROM directory.
-+++++-- On Win32 working directory must have drive letter ????
-+++++-- On Win32 working directory must be writable by SYSTEM to
-+++++- do restores.
-+++++-- Document that ChangerDevice is used for Alert command.
-+++++-- Add better documentation on how restores can be done
-+++++-8. Take one more try at making DVD writing work (no go)
-+++++-7. Write a bacula-web document
-+++++-- Why isn't the DEVICE structure defined when doing
-+++++- a reservation?
-+++++-- Multi-drive changer seems to only use drive 0
-+++++- Multiple drives don't seem to be opened.
-+++++-- My database is growing
-+++++-- Call GetLastError() in the berrno constructor rather
-+++++- than delaying until strerror.
-+++++-- Tape xxx in drive 0, requested in drive 1
-+++++-- The mount command does not work with drives other than 0.
-+++++-- A mount should cause the SD to re-examine what Slot is
-+++++- loaded.
-+++++-- The SD locks on to the first available drive then
-+++++- wants a Volume that is released but in another drive --
-+++++- chaos.
-+++++-- Run the regression scripts on Solaris and FreeBSD
-+++++-- Figure out how to package gui, and rescue programs.
-+++++-- Add a .dir command to restore tree code to eliminate the problem
-+++++-- Mount after manually unloading changer causes hang in SD
-+++++-- Fix JobACL with restore by JobId.
-++++++=== Done -- see kernsdone
-+++++Index: kes-1.38
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-+++++retrieving revision 1.1.2.13
-+++++diff -u -r1.1.2.13 kes-1.38
-+++++--- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-++++++++ kes-1.38 21 Nov 2005 13:13:00 -0000
-+++++@@ -3,6 +3,18 @@
-+++++
-+++++ General:
-+++++
-++++++Changes to 1.38.2:
-++++++20Oct05
-++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++++- Fix bnet-server bug found on OpenBSD. Bug #486
-++++++- Fix cancel failure bug. Bug #481
-++++++- Fix failure when Pool name has spaces. Bug #487
-++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++++- Fix a couple of free()s in src/filed/acl.c
-++++++- Fix memory overrun in bfile.c in building OS X resource
-++++++ fork filename. Bug #489
-++++++- Add Pool name to SD status output.
-++++++
-+++++ Changes to 1.38.1:
-+++++ 14Oct05
-+++++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-+++++Index: projects
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/projects,v
-+++++retrieving revision 1.12.2.3
-+++++diff -u -r1.12.2.3 projects
-+++++--- projects 10 Nov 2005 20:25:27 -0000 1.12.2.3
-++++++++ projects 21 Nov 2005 13:13:00 -0000
-+++++@@ -228,7 +228,175 @@
-+++++
-+++++ Why: Performance enhancement.
-+++++
-++++++Item 13: Let Bacula log tape usage and handle drive cleaning cycles.
-++++++ Date: November 11, 2005
-++++++ Origin: Arno Lehmann <al at its-lehmann dot de>
-++++++ Status:
-++++++
-++++++ What: Make Bacula manage tape life cycle information and drive
-++++++ cleaning cycles.
-++++++
-++++++ Why: Both parts of this project are important when operating backups.
-++++++ We need to know which tapes need replacement, and we need to
-++++++ make sure the drives are cleaned when necessary. While many
-++++++ tape libraries and even autoloaders can handle all this
-++++++ automatically, support by Bacula can be helpful for smaller
-++++++ (older) libraries and single drives. Also, checking drive
-++++++ status during operation can prevent some failures (as I had to
-++++++ learn the hard way...)
-++++++
-++++++ Notes: First, Bacula could (and even does, to some limited extent)
-++++++ record tape and drive usage. For tapes, the number of mounts,
-++++++ the amount of data, and the time the tape has actually been
-++++++ running could be recorded. Data fields for Read and Write time
-++++++ and Nmber of mounts already exist in the catalog (I'm not sure
-++++++ if VolBytes is the sum of all bytes ever written to that volume
-++++++ by Bacula). This information can be important when determining
-++++++ which media to replace. For the tape drives known to Bacula,
-++++++ similar information is interesting to determine the device
-++++++ status and expected life time: Time it's been Reading and
-++++++ Writing, number of tape Loads / Unloads / Errors. This
-++++++ information is not yet recorded as far as I know.
-++++++
-++++++ The next step would be implementing drive cleaning setup.
-++++++ Bacula already has knowledge about cleaning tapes. Once it has
-++++++ some information about cleaning cycles (measured in drive run
-++++++ time, number of tapes used, or calender days, for example) it
-++++++ can automatically execute tape cleaning (with an autochanger,
-++++++ obviously) or ask for operator assistence loading a cleaning
-++++++ tape.
-++++++
-++++++ The next step would be to implement TAPEALERT checks not only
-++++++ when changing tapes and only sending he information to the
-++++++ administrator, but rather checking after each tape error,
-++++++ checking on a regular basis (for example after each tape file),
-++++++ and also before unloading and after loading a new tape. Then,
-++++++ depending on the drives TAPEALERT state and the know drive
-++++++ cleaning state Bacula could automatically schedule later
-++++++ cleaning, clean immediately, or inform the operator.
-++++++
-++++++ Implementing this would perhaps require another catalog change
-++++++ and perhaps major changes in SD code and the DIR-SD protocoll,
-++++++ so I'd only consider this worth implementing if it would
-++++++ actually be used or even needed by many people.
-++++++
-++++++Item 14: Merging of multiple backups into a single one. (Also called Synthetic
-++++++ Backup or Consolidation).
-++++++
-++++++ Origin: Marc Cousin and Eric Bollengier
-++++++ Date: 15 November 2005
-++++++ Status: Depends on first implementing project Item 1 (Migration).
-++++++
-++++++ What: A merged backup is a backup made without connecting to the Client.
-++++++ It would be a Merge of existing backups into a single backup.
-++++++ In effect, it is like a restore but to the backup medium.
-++++++
-++++++ For instance, say that last sunday we made a full backup. Then
-++++++ all week long, we created incremental backups, in order to do
-++++++ them fast. Now comes sunday again, and we need another full.
-++++++ The merged backup makes it possible to do instead an incremental
-++++++ backup (during the night for instance), and then create a merged
-++++++ backup during the day, by using the full and incrementals from
-++++++ the week. The merged backup will be exactly like a full made
-++++++ sunday night on the tape, but the production interruption on the
-++++++ Client will be minimal, as the Client will only have to send
-++++++ incrementals.
-++++++
-++++++ In fact, if it's done correctly, you could merge all the
-++++++ Incrementals into single Incremental, or all the Incrementals
-++++++ and the last Differential into a new Differential, or the Full,
-++++++ last differential and all the Incrementals into a new Full
-++++++ backup. And there is no need to involve the Client.
-++++++
-++++++ Why: The benefit is that :
-++++++ - the Client just does an incremental ;
-++++++ - the merged backup on tape is just as a single full backup,
-++++++ and can be restored very fast.
-++++++
-++++++ This is also a way of reducing the backup data since the old
-++++++ data can then be pruned (or not) from the catalog, possibly
-++++++ allowing older volumes to be recycled
-++++++
-++++++Item 15: Automatic disabling of devices
-++++++ Date: 2005-11-11
-++++++ Origin: Peter Eriksson <peter at ifm.liu dot se>
-++++++ Status:
-++++++
-++++++ What: After a configurable amount of fatal errors with a tape drive
-++++++ Bacula should automatically disable further use of a certain
-++++++ tape drive. There should also be "disable"/"enable" commands in
-++++++ the "bconsole" tool.
-++++++
-++++++ Why: On a multi-drive jukebox there is a possibility of tape drives
-++++++ going bad during large backups (needing a cleaning tape run,
-++++++ tapes getting stuck). It would be advantageous if Bacula would
-++++++ automatically disable further use of a problematic tape drive
-++++++ after a configurable amount of errors has occured.
-++++++
-++++++ An example: I have a multi-drive jukebox (6 drives, 380+ slots)
-++++++ where tapes occasionally get stuck inside the drive. Bacula will
-++++++ notice that the "mtx-changer" command will fail and then fail
-++++++ any backup jobs trying to use that drive. However, it will still
-++++++ keep on trying to run new jobs using that drive and fail -
-++++++ forever, and thus failing lots and lots of jobs... Since we have
-++++++ many drives Bacula could have just automatically disabled
-++++++ further use of that drive and used one of the other ones
-++++++ instead.
-++++++
-++++++
-++++++Item 16: Directive/mode to backup only file changes, not entire file
-++++++ Date: 11 November 2005
-++++++ Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
-++++++ Marek Bajon <mbajon at bimsplus dot com dot pl>
-++++++ Status: RFC
-++++++
-++++++ What: Currently when a file changes, the entire file will be backed up in
-++++++ the next incremental or full backup. To save space on the tapes
-++++++ it would be nice to have a mode whereby only the changes to the
-++++++ file would be backed up when it is changed.
-++++++
-++++++ Why: This would save lots of space when backing up large files such as
-++++++ logs, mbox files, Outlook PST files and the like.
-++++++
-++++++ Notes: This would require the usage of disk-based volumes as comparing
-++++++ files would not be feasible using a tape drive.
-++++++
-++++++Item 17: Quick release of FD-SD connection
-++++++ Origin: Frank Volf (frank at deze dot org)
-++++++ Date: 17 november 2005
-++++++ Status:
-++++++
-++++++ What: In the bacula implementation a backup is finished after all data
-++++++ and attributes are succesfully written to storage. When using a
-++++++ tape backup it is very annoying that a backup can take a day,
-++++++ simply because the current tape (or whatever) is full and the
-++++++ administrator has not put a new one in. During that time the
-++++++ system cannot be taken off-line, because there is still an open
-++++++ session between the storage daemon and the file daemon on the
-++++++ client.
-++++++
-++++++ Although this is a very good strategey for making "safe backups"
-++++++ This can be annoying for e.g. laptops, that must remain
-++++++ connected until the bacukp is completed.
-++++++
-++++++ Using a new feature called "migration" it will be possible to
-++++++ spool first to harddisk (using a special 'spool' migration
-++++++ scheme) and then migrate the backup to tape.
-++++++
-++++++ There is still the problem of getting the attributes committed.
-++++++ If it takes a very long time to do, with the current code, the
-++++++ job has not terminated, and the File daemon is not freed up. The
-++++++ Storage daemon should release the File daemon as soon as all the
-++++++ file data and all the attributes have been sent to it (the SD).
-++++++ Currently the SD waits until everything is on tape and all the
-++++++ attributes are transmitted to the Director before signalling
-++++++ completion to the FD. I don't think I would have any problem
-++++++ changing this. The reason is that even if the FD reports back to
-++++++ the Dir that all is OK, the job will not terminate until the SD
-++++++ has done the same thing -- so in a way keeping the SD-FD link
-++++++ open to the very end is not really very productive ...
-+++++
-++++++ Why: Makes backup of laptops much easier.
-+++++
-+++++
-+++++ ============= Empty RFC form ===========
-+++++@@ -245,33 +413,4 @@
-+++++ ============== End RFC form ==============
-+++++
-+++++
-+++++-Items completed for release 1.38.0:
-+++++-#4 Embedded Python Scripting (implemented in all Daemons)
-+++++-#5 Events that call a Python program (Implemented in all
-+++++- daemons, but more cleanup work to be done).
-+++++-#6 Select one from among Multiple Storage Devices for Job.
-+++++- This is already implemented in 1.37.
-+++++-#7 Single Job Writing to Multiple Storage Devices. This is
-+++++- currently implemented with a Clone feature.
-+++++-#- Full multiple drive Autochanger support (done in 1.37)
-+++++-#- Built in support for communications encryption (TLS)
-+++++- done by Landon Fuller.
-+++++-# Support for Unicode characters
-+++++- (via UTF-8) on Win32 machines thanks to Thorsten Engel.
-+++++-Item 8: Break the one-to-one Relationship between a Job and a
-+++++- Specific Storage Device (or Devices if #10 is implemented).
-+++++-
-+++++-Completed items from last year's list:
-+++++-Item 1: Multiple simultaneous Jobs. (done)
-+++++-Item 3: Write the bscan program -- also write a bcopy program (done).
-+++++-Item 5: Implement Label templates (done).
-+++++-Item 6: Write a regression script (done)
-+++++-Item 9: Add SSL to daemon communications (done by Landon Fuller)
-+++++-Item 10: Define definitive tape format (done)
-+++++-Item 3: GUI for interactive restore. Partially Implemented in 1.34
-+++++- Note, there is now a complete Webmin plugin, a partial
-+++++- GNOME console, and an excellent wx-console GUI.
-+++++-Item 4: GUI for interactive backup
-+++++-Item 2: Job Data Spooling.
-+++++- Done: Regular expression matching.
-+++++-Item 10: New daemon communication protocol (this has been dropped).
-++++++Items completed for release 1.38.0 -- see kernsdone
-+++++Index: patches/1.38.1-to-1.38.2.patch
-+++++===================================================================
-+++++RCS file: patches/1.38.1-to-1.38.2.patch
-+++++diff -N patches/1.38.1-to-1.38.2.patch
-+++++--- /dev/null 1 Jan 1970 00:00:00 -0000
-++++++++ patches/1.38.1-to-1.38.2.patch 21 Nov 2005 13:13:01 -0000
-+++++@@ -0,0 +1,1414 @@
-++++++
-++++++ This patch fixes the following bugs:
-++++++
-++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++++++ says that this patch does not fix his problem)
-++++++- Fix cancel failure bug. Bug #481
-++++++- Fix failure when Pool name has spaces. Bug #487
-++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++++- Fix a couple of free()s in src/filed/acl.c
-++++++- Fix memory overrun in bfile.c in building OS X resource
-++++++ fork filename. Bug #489
-++++++
-++++++This patch is applied to Bacula source version 1.38.1 and will
-++++++produce Bacula source version 1.38.2. Apply it with:
-++++++
-++++++ cd <bacula-1.38.1-source>
-++++++ ./configure (your options) if not already done
-++++++ patch -p0 <1.38.1-to-1.38.2.patch
-++++++ make
-++++++ make install
-++++++
-++++++? osx_finder.patch
-++++++Index: kernstodo
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/kernstodo,v
-++++++retrieving revision 1.570.2.6
-++++++diff -u -r1.570.2.6 kernstodo
-++++++--- kernstodo 4 Nov 2005 09:16:49 -0000 1.570.2.6
-+++++++++ kernstodo 21 Nov 2005 13:06:36 -0000
-++++++@@ -1,5 +1,5 @@
-++++++ Kern's ToDo List
-++++++- 03 November 2005
-+++++++ 21 November 2005
-++++++
-++++++ Major development:
-++++++ Project Developer
-++++++@@ -7,8 +7,6 @@
-++++++ Version 1.37 Kern (see below)
-++++++ ========================================================
-++++++
-++++++-Final items for 1.37 before release:
-++++++-
-++++++ Document:
-++++++ - Does ClientRunAfterJob fail the job on a bad return code?
-++++++ - Document cleaning up the spool files:
-++++++@@ -18,6 +16,8 @@
-++++++ - Does WildFile match against full name? Doc.
-++++++
-++++++ For 1.39:
-+++++++- Make sure that all do_prompt() calls in Dir check for
-+++++++ -1 (error) and -2 (cancel) returns.
-++++++ - Look at -D_FORTIFY_SOURCE=2
-++++++ - Add Win32 FileSet definition somewhere
-++++++ - Look at fixing restore status stats in SD.
-++++++@@ -27,6 +27,12 @@
-++++++ encountered, read many times (as it currently does), and if the
-++++++ block cannot be read, skip to the next block, and try again. If
-++++++ that fails, skip to the next file and try again, ...
-+++++++- Add level table:
-+++++++ create table LevelType (LevelType binary(1), LevelTypeLong tinyblob);
-+++++++ insert into LevelType (LevelType,LevelTypeLong) values
-+++++++ ("F","Full"),
-+++++++ ("D","Diff"),
-+++++++ ("I","Inc");
-++++++ - Add ACL to restore only to original location.
-++++++ - Add a recursive mark command (rmark) to restore.
-++++++ - "Minimum Job Interval = nnn" sets minimum interval between Jobs
-++++++@@ -1246,219 +1252,4 @@
-++++++ ====
-++++++
-++++++
-++++++-=== Done
-++++++-- Save mount point for directories not traversed with onefs=yes.
-++++++-- Add seconds to start and end times in the Job report output.
-++++++-- if 2 concurrent backups are attempted on the same tape
-++++++- drive (autoloader) into different tape pools, one of them will exit
-++++++- fatally instead of halting until the drive is idle
-++++++-- Update StartTime if job held in Job Queue.
-++++++-- Look at www.nu2.nu/pebuilder as a helper for full windows
-++++++- bare metal restore. (done by Scott)
-++++++-- Fix orphanned buffers:
-++++++- Orphaned buffer: 24 bytes allocated at line 808 of rufus-dir job.c
-++++++- Orphaned buffer: 40 bytes allocated at line 45 of rufus-dir alist.c
-++++++-- Implement Preben's suggestion to add
-++++++- File System Types = ext2, ext3
-++++++- to FileSets, thus simplifying backup of *all* local partitions.
-++++++-- Try to open a device on each Job if it was not opened
-++++++- when the SD started.
-++++++-- Add dump of VolSessionId/Time and FileIndex with bls.
-++++++-- If Bacula does not find the right tape in the Autochanger,
-++++++- then mark the tape in error and move on rather than asking
-++++++- for operator intervention.
-++++++-- Cancel command should include JobId in list of Jobs.
-++++++-- Add performance testing hooks
-++++++-- Bootstrap from JobMedia records.
-++++++-- Implement WildFile and WildDir to solve problem of
-++++++- saving only *.doc files.
-++++++-- Fix
-++++++- Please use the "label" command to create a new Volume for:
-++++++- Storage: DDS-4-changer
-++++++- Media type:
-++++++- Pool: Default
-++++++- label
-++++++- The defined Storage resources are:
-++++++-- Copy Changer Device and Changer Command from Autochanger
-++++++- to Device resource in SD if none given in Device resource.
-++++++-- 1. Automatic use of more than one drive in an autochanger (done)
-++++++-- 2. Automatic selection of the correct drive for each Job (i.e.
-++++++- selects a drive with an appropriate Volume for the Job) (done)
-++++++-- 6. Allow multiple simultaneous Jobs referencing the same pool write
-++++++- to several tapes (some new directive(s) are are probably needed for
-++++++- this) (done)
-++++++-- Locking (done)
-++++++-- Key on Storage rather than Pool (done)
-++++++-- Allow multiple drives to use same Pool (change jobq.c DIR) (done).
-++++++-- Synchronize multiple drives so that not more
-++++++- than one loads a tape and any time (done)
-++++++-- 4. Use Changer Device and Changer Command specified in the
-++++++- Autochanger resource, if none is found in the Device resource.
-++++++- You can continue to specify them in the Device resource if you want
-++++++- or need them to be different for each device.
-++++++-- 5. Implement a new Device directive (perhaps "Autoselect = yes/no")
-++++++- that can allow a Device be part of an Autochanger, and hence the changer
-++++++- script protected, but if set to no, will prevent the Device from being
-++++++- automatically selected from the changer. This allows the device to
-++++++- be directly accessed through its Device name, but not through the
-++++++- AutoChanger name.
-++++++-#6 Select one from among Multiple Storage Devices for Job
-++++++-#5 Events that call a Python program
-++++++- (Implemented in Dir/SD)
-++++++-- Make sure the Device name is in the Query packet returned.
-++++++-- Don't start a second file job if one is already running.
-++++++-- Implement EOF/EOV labels for ANSI labels
-++++++-- Implement IBM labels.
-++++++-- When Python creates a new label, the tape is immediately
-++++++- recycled and no label created. This happens when using
-++++++- autolabeling -- even when Python doesn't generate the name.
-++++++-- Scratch Pool where the volumes can be re-assigned to any Pool.
-++++++-- 28-Mar 23:19 rufus-sd: acquire.c:379 Device "DDS-4" (/dev/nst0)
-++++++- is busy reading. Job 6 canceled.
-++++++-- Remove separate thread for opening devices in SD. On the other
-++++++- hand, don't block waiting for open() for devices.
-++++++-- Fix code to either handle updating NumVol or to calculate it in
-++++++- Dir next_vol.c
-++++++-- Ensure that you cannot exclude a directory or a file explicitly
-++++++- Included with File.
-++++++-#4 Embedded Python Scripting
-++++++- (Implemented in Dir/SD/FD)
-++++++-- Add Python writable variable for changing the Priority,
-++++++- Client, Storage, JobStatus (error), ...
-++++++-- SD Python
-++++++- - Solicit Events
-++++++-- Add disk seeking on restore; turn off seek on tapes.
-++++++- stored/match_bsr.c
-++++++-- Look at dird_conf.c:1000: warning: `int size'
-++++++- might be used uninitialized in this function
-++++++-- Indicate when a Job is purged/pruned during restore.
-++++++-- Implement some way to turn off automatic pruning in Jobs.
-++++++-- Implement a way an Admin Job can prune, possibly multiple
-++++++- clients -- Python script?
-++++++-- Look at Preben's acl.c error handling code.
-++++++-- SD crashes after a tape restore then doing a backup.
-++++++-- If drive is opened read/write, close it and re-open
-++++++- read-only if doing a restore, and vice-versa.
-++++++-- Windows restore:
-++++++- data-fd: RestoreFiles.2004-12-07_15.56.42 Error:
-++++++- > ..\findlib\../../findlib/create_file.c:275 Could not open e:/: ERR=Der
-++++++- > Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen
-++++++- > Prozess verwendet wird.
-++++++- Restore restores all files, but then fails at the end trying
-++++++- to set the attributes of e:
-++++++- from failed jobs.- Resolve the problem between Device name and Archive name,
-++++++- and fix SD messages.
-++++++-- Tell the "restore" user when browsing is no longer possible.
-++++++-- Add a restore directory-x
-++++++-- Write non-optimized bsrs from the JobMedia and Media records,
-++++++- even after Files are pruned.
-++++++-- Delete Stripe and Copy from VolParams to save space.
-++++++-- Fix option 2 of restore -- list where file is backed up -- require Client,
-++++++- then list last 20 backups.
-++++++-- Finish implementation of passing all Storage and Device needs to
-++++++- the SD.
-++++++-- Move test for max wait time exceeded in job.c up -- Peter's idea.
-++++++-## Consider moving docs to their own project.
-++++++-## Move rescue to its own project.
-++++++-- Add client version to the Client name line that prints in
-++++++- the Job report.
-++++++-- Fix the Rescue CDROM.
-++++++-- By the way: on page http://www.bacula.org/?page=tapedrives , at the
-++++++- bottom, the link to "Tape Testing Chapter" is broken. It goes to
-++++++- /html-manual/... while the others point to /rel-manual/...
-++++++-- Device resource needs the "name" of the SD.
-++++++-- Specify a single directory to restore.
-++++++-- Implement MediaType keyword in bsr?
-++++++-- Add a date and time stamp at the beginning of every line in the
-++++++- Job report (Volker Sauer).
-++++++-- Add level to estimate command.
-++++++-- Add "limit=n" for "list jobs"
-++++++-- Make bootstrap filename unique.
-++++++-- Make Dmsg look at global before calling subroutine.
-++++++-- From Chris Hull:
-++++++- it seems to be complaining about 12:00pm which should be a valid 12
-++++++- hour time. I changed the time to 11:59am and everything works fine.
-++++++- Also 12:00am works fine. 0:00pm also works (which I don't think
-++++++- should). None of the values 12:00pm - 12:59pm work for that matter.
-++++++-- Require restore via the restore command or make a restore Job
-++++++- get the bootstrap file.
-++++++-- Implement Maximum Job Spool Size
-++++++-- Fix 3993 error in SD. It forgets to look at autochanger
-++++++- resource for device command, ...
-++++++-- 3. Prevent two drives requesting the same Volume in any given
-++++++- autochanger, by checking if a Volume is mounted on another drive
-++++++- in an Autochanger.
-++++++-- Upgrade to MySQL 4.1.12 See:
-++++++- http://dev.mysql.com/doc/mysql/en/Server_SQL_mode.html
-++++++-- Add # Job Level date to bsr file
-++++++-- Implement "PreferMountedVolumes = yes|no" in Job resource.
-++++++-## Integrate web-bacula into a new Bacula project with
-++++++- bimagemgr.
-++++++-- Cleaning tapes should have Status "Cleaning" rather than append.
-++++++-- Make sure that Python has access to Client address/port so that
-++++++- it can check if Clients are alive.
-++++++-- Review all items in "restore".
-++++++-- Fix PostgreSQL GROUP BY problems in restore.
-++++++-- Fix PostgreSQL sql problems in bugs.
-++++++-- After rename
-++++++- 04-Jul 13:01 MainSD: Rufus.2005-07-04_01.05.02 Warning: Director wanted Volume
-++++++- "DLT-13Feb04".
-++++++- Current Volume "DLT-04Jul05" not acceptable because:
-++++++- 1997 Volume "DLT-13Feb04" not in catalog.
-++++++- 04-Jul 13:01 MainSD: Please mount Volume "DLT-04Jul05" on Storage Device
-++++++- "HP DLT 80" (/dev/nst0) for Job Rufus.2005-07-04_01.05.02
-++++++-## Create a new GUI chapter explaining all the GUI programs.
-++++++-- Make "update slots" when pointing to Autochanger, remove
-++++++- all Volumes from other drives. "update slots all-drives"?
-++++++- No, this is done by modifying mtx-changer to list what is
-++++++- in the drives.
-++++++-- Finish TLS implementation.
-++++++-- Port limiting -m in iptables to prevent DoS attacks
-++++++- could cause broken pipes on Bacula.
-++++++-6. Build and test the Volume Shadow Copy (VSS) for Win32.
-++++++-- Allow cancel of unknown Job
-++++++-- State not saved when closing Win32 FD by icon
-++++++-- bsr-opt-test fails. bsr deleted. Fix.
-++++++-- Move Python daemon variables from Job to Bacula object.
-++++++- WorkingDir, ConfigFile
-++++++-- Document that Bootstrap files can be written with cataloging
-++++++- turned off.
-++++++-- Document details of ANSI/IBM labels
-++++++-- OS linux 2.4
-++++++- 1) ADIC, DLT, FastStor 4000, 7*20GB
-++++++-- Linux Sony LIB-D81, AIT-3 library works.
-++++++-- Doc the following
-++++++- to activate, check or disable the hardware compression feature on my
-++++++- exb-8900 i use the exabyte "MammothTool" you can get it here:
-++++++- http://www.exabyte.com/support/online/downloads/index.cfm
-++++++- There is a solaris version of this tool. With option -C 0 or 1 you can
-++++++- disable or activate compression. Start this tool without any options for
-++++++- a small reference.
-++++++-- Document Heartbeat Interval in the dealing with firewalls section.
-++++++-- Document new CDROM directory.
-++++++-- On Win32 working directory must have drive letter ????
-++++++-- On Win32 working directory must be writable by SYSTEM to
-++++++- do restores.
-++++++-- Document that ChangerDevice is used for Alert command.
-++++++-- Add better documentation on how restores can be done
-++++++-8. Take one more try at making DVD writing work (no go)
-++++++-7. Write a bacula-web document
-++++++-- Why isn't the DEVICE structure defined when doing
-++++++- a reservation?
-++++++-- Multi-drive changer seems to only use drive 0
-++++++- Multiple drives don't seem to be opened.
-++++++-- My database is growing
-++++++-- Call GetLastError() in the berrno constructor rather
-++++++- than delaying until strerror.
-++++++-- Tape xxx in drive 0, requested in drive 1
-++++++-- The mount command does not work with drives other than 0.
-++++++-- A mount should cause the SD to re-examine what Slot is
-++++++- loaded.
-++++++-- The SD locks on to the first available drive then
-++++++- wants a Volume that is released but in another drive --
-++++++- chaos.
-++++++-- Run the regression scripts on Solaris and FreeBSD
-++++++-- Figure out how to package gui, and rescue programs.
-++++++-- Add a .dir command to restore tree code to eliminate the problem
-++++++-- Mount after manually unloading changer causes hang in SD
-++++++-- Fix JobACL with restore by JobId.
-+++++++=== Done -- see kernsdone
-++++++Index: kes-1.38
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-++++++retrieving revision 1.1.2.13
-++++++diff -u -r1.1.2.13 kes-1.38
-++++++--- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-+++++++++ kes-1.38 21 Nov 2005 13:06:36 -0000
-++++++@@ -3,6 +3,17 @@
-++++++
-++++++ General:
-++++++
-+++++++Changes after release of 1.38.1:
-+++++++20Oct05
-+++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++++- Fix bnet-server bug found on OpenBSD. Bug #486
-+++++++- Fix cancel failure bug. Bug #481
-+++++++- Fix failure when Pool name has spaces. Bug #487
-+++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++++- Fix a couple of free()s in src/filed/acl.c
-+++++++- Fix memory overrun in bfile.c in building OS X resource
-+++++++ fork filename. Bug #489
-+++++++
-++++++ Changes to 1.38.1:
-++++++ 14Oct05
-++++++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-++++++Index: projects
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/projects,v
-++++++retrieving revision 1.12.2.3
-++++++diff -u -r1.12.2.3 projects
-++++++--- projects 10 Nov 2005 20:25:27 -0000 1.12.2.3
-+++++++++ projects 21 Nov 2005 13:06:37 -0000
-++++++@@ -228,7 +228,175 @@
-++++++
-++++++ Why: Performance enhancement.
-++++++
-+++++++Item 13: Let Bacula log tape usage and handle drive cleaning cycles.
-+++++++ Date: November 11, 2005
-+++++++ Origin: Arno Lehmann <al at its-lehmann dot de>
-+++++++ Status:
-+++++++
-+++++++ What: Make Bacula manage tape life cycle information and drive
-+++++++ cleaning cycles.
-+++++++
-+++++++ Why: Both parts of this project are important when operating backups.
-+++++++ We need to know which tapes need replacement, and we need to
-+++++++ make sure the drives are cleaned when necessary. While many
-+++++++ tape libraries and even autoloaders can handle all this
-+++++++ automatically, support by Bacula can be helpful for smaller
-+++++++ (older) libraries and single drives. Also, checking drive
-+++++++ status during operation can prevent some failures (as I had to
-+++++++ learn the hard way...)
-+++++++
-+++++++ Notes: First, Bacula could (and even does, to some limited extent)
-+++++++ record tape and drive usage. For tapes, the number of mounts,
-+++++++ the amount of data, and the time the tape has actually been
-+++++++ running could be recorded. Data fields for Read and Write time
-+++++++ and Nmber of mounts already exist in the catalog (I'm not sure
-+++++++ if VolBytes is the sum of all bytes ever written to that volume
-+++++++ by Bacula). This information can be important when determining
-+++++++ which media to replace. For the tape drives known to Bacula,
-+++++++ similar information is interesting to determine the device
-+++++++ status and expected life time: Time it's been Reading and
-+++++++ Writing, number of tape Loads / Unloads / Errors. This
-+++++++ information is not yet recorded as far as I know.
-+++++++
-+++++++ The next step would be implementing drive cleaning setup.
-+++++++ Bacula already has knowledge about cleaning tapes. Once it has
-+++++++ some information about cleaning cycles (measured in drive run
-+++++++ time, number of tapes used, or calender days, for example) it
-+++++++ can automatically execute tape cleaning (with an autochanger,
-+++++++ obviously) or ask for operator assistence loading a cleaning
-+++++++ tape.
-+++++++
-+++++++ The next step would be to implement TAPEALERT checks not only
-+++++++ when changing tapes and only sending he information to the
-+++++++ administrator, but rather checking after each tape error,
-+++++++ checking on a regular basis (for example after each tape file),
-+++++++ and also before unloading and after loading a new tape. Then,
-+++++++ depending on the drives TAPEALERT state and the know drive
-+++++++ cleaning state Bacula could automatically schedule later
-+++++++ cleaning, clean immediately, or inform the operator.
-+++++++
-+++++++ Implementing this would perhaps require another catalog change
-+++++++ and perhaps major changes in SD code and the DIR-SD protocoll,
-+++++++ so I'd only consider this worth implementing if it would
-+++++++ actually be used or even needed by many people.
-+++++++
-+++++++Item 14: Merging of multiple backups into a single one. (Also called Synthetic
-+++++++ Backup or Consolidation).
-+++++++
-+++++++ Origin: Marc Cousin and Eric Bollengier
-+++++++ Date: 15 November 2005
-+++++++ Status: Depends on first implementing project Item 1 (Migration).
-+++++++
-+++++++ What: A merged backup is a backup made without connecting to the Client.
-+++++++ It would be a Merge of existing backups into a single backup.
-+++++++ In effect, it is like a restore but to the backup medium.
-+++++++
-+++++++ For instance, say that last sunday we made a full backup. Then
-+++++++ all week long, we created incremental backups, in order to do
-+++++++ them fast. Now comes sunday again, and we need another full.
-+++++++ The merged backup makes it possible to do instead an incremental
-+++++++ backup (during the night for instance), and then create a merged
-+++++++ backup during the day, by using the full and incrementals from
-+++++++ the week. The merged backup will be exactly like a full made
-+++++++ sunday night on the tape, but the production interruption on the
-+++++++ Client will be minimal, as the Client will only have to send
-+++++++ incrementals.
-+++++++
-+++++++ In fact, if it's done correctly, you could merge all the
-+++++++ Incrementals into single Incremental, or all the Incrementals
-+++++++ and the last Differential into a new Differential, or the Full,
-+++++++ last differential and all the Incrementals into a new Full
-+++++++ backup. And there is no need to involve the Client.
-+++++++
-+++++++ Why: The benefit is that :
-+++++++ - the Client just does an incremental ;
-+++++++ - the merged backup on tape is just as a single full backup,
-+++++++ and can be restored very fast.
-+++++++
-+++++++ This is also a way of reducing the backup data since the old
-+++++++ data can then be pruned (or not) from the catalog, possibly
-+++++++ allowing older volumes to be recycled
-+++++++
-+++++++Item 15: Automatic disabling of devices
-+++++++ Date: 2005-11-11
-+++++++ Origin: Peter Eriksson <peter at ifm.liu dot se>
-+++++++ Status:
-+++++++
-+++++++ What: After a configurable amount of fatal errors with a tape drive
-+++++++ Bacula should automatically disable further use of a certain
-+++++++ tape drive. There should also be "disable"/"enable" commands in
-+++++++ the "bconsole" tool.
-+++++++
-+++++++ Why: On a multi-drive jukebox there is a possibility of tape drives
-+++++++ going bad during large backups (needing a cleaning tape run,
-+++++++ tapes getting stuck). It would be advantageous if Bacula would
-+++++++ automatically disable further use of a problematic tape drive
-+++++++ after a configurable amount of errors has occured.
-+++++++
-+++++++ An example: I have a multi-drive jukebox (6 drives, 380+ slots)
-+++++++ where tapes occasionally get stuck inside the drive. Bacula will
-+++++++ notice that the "mtx-changer" command will fail and then fail
-+++++++ any backup jobs trying to use that drive. However, it will still
-+++++++ keep on trying to run new jobs using that drive and fail -
-+++++++ forever, and thus failing lots and lots of jobs... Since we have
-+++++++ many drives Bacula could have just automatically disabled
-+++++++ further use of that drive and used one of the other ones
-+++++++ instead.
-+++++++
-+++++++
-+++++++Item 16: Directive/mode to backup only file changes, not entire file
-+++++++ Date: 11 November 2005
-+++++++ Origin: Joshua Kugler <joshua dot kugler at uaf dot edu>
-+++++++ Marek Bajon <mbajon at bimsplus dot com dot pl>
-+++++++ Status: RFC
-+++++++
-+++++++ What: Currently when a file changes, the entire file will be backed up in
-+++++++ the next incremental or full backup. To save space on the tapes
-+++++++ it would be nice to have a mode whereby only the changes to the
-+++++++ file would be backed up when it is changed.
-+++++++
-+++++++ Why: This would save lots of space when backing up large files such as
-+++++++ logs, mbox files, Outlook PST files and the like.
-+++++++
-+++++++ Notes: This would require the usage of disk-based volumes as comparing
-+++++++ files would not be feasible using a tape drive.
-+++++++
-+++++++Item 17: Quick release of FD-SD connection
-+++++++ Origin: Frank Volf (frank at deze dot org)
-+++++++ Date: 17 november 2005
-+++++++ Status:
-+++++++
-+++++++ What: In the bacula implementation a backup is finished after all data
-+++++++ and attributes are succesfully written to storage. When using a
-+++++++ tape backup it is very annoying that a backup can take a day,
-+++++++ simply because the current tape (or whatever) is full and the
-+++++++ administrator has not put a new one in. During that time the
-+++++++ system cannot be taken off-line, because there is still an open
-+++++++ session between the storage daemon and the file daemon on the
-+++++++ client.
-+++++++
-+++++++ Although this is a very good strategey for making "safe backups"
-+++++++ This can be annoying for e.g. laptops, that must remain
-+++++++ connected until the bacukp is completed.
-+++++++
-+++++++ Using a new feature called "migration" it will be possible to
-+++++++ spool first to harddisk (using a special 'spool' migration
-+++++++ scheme) and then migrate the backup to tape.
-+++++++
-+++++++ There is still the problem of getting the attributes committed.
-+++++++ If it takes a very long time to do, with the current code, the
-+++++++ job has not terminated, and the File daemon is not freed up. The
-+++++++ Storage daemon should release the File daemon as soon as all the
-+++++++ file data and all the attributes have been sent to it (the SD).
-+++++++ Currently the SD waits until everything is on tape and all the
-+++++++ attributes are transmitted to the Director before signalling
-+++++++ completion to the FD. I don't think I would have any problem
-+++++++ changing this. The reason is that even if the FD reports back to
-+++++++ the Dir that all is OK, the job will not terminate until the SD
-+++++++ has done the same thing -- so in a way keeping the SD-FD link
-+++++++ open to the very end is not really very productive ...
-++++++
-+++++++ Why: Makes backup of laptops much easier.
-++++++
-++++++
-++++++ ============= Empty RFC form ===========
-++++++@@ -245,33 +413,4 @@
-++++++ ============== End RFC form ==============
-++++++
-++++++
-++++++-Items completed for release 1.38.0:
-++++++-#4 Embedded Python Scripting (implemented in all Daemons)
-++++++-#5 Events that call a Python program (Implemented in all
-++++++- daemons, but more cleanup work to be done).
-++++++-#6 Select one from among Multiple Storage Devices for Job.
-++++++- This is already implemented in 1.37.
-++++++-#7 Single Job Writing to Multiple Storage Devices. This is
-++++++- currently implemented with a Clone feature.
-++++++-#- Full multiple drive Autochanger support (done in 1.37)
-++++++-#- Built in support for communications encryption (TLS)
-++++++- done by Landon Fuller.
-++++++-# Support for Unicode characters
-++++++- (via UTF-8) on Win32 machines thanks to Thorsten Engel.
-++++++-Item 8: Break the one-to-one Relationship between a Job and a
-++++++- Specific Storage Device (or Devices if #10 is implemented).
-++++++-
-++++++-Completed items from last year's list:
-++++++-Item 1: Multiple simultaneous Jobs. (done)
-++++++-Item 3: Write the bscan program -- also write a bcopy program (done).
-++++++-Item 5: Implement Label templates (done).
-++++++-Item 6: Write a regression script (done)
-++++++-Item 9: Add SSL to daemon communications (done by Landon Fuller)
-++++++-Item 10: Define definitive tape format (done)
-++++++-Item 3: GUI for interactive restore. Partially Implemented in 1.34
-++++++- Note, there is now a complete Webmin plugin, a partial
-++++++- GNOME console, and an excellent wx-console GUI.
-++++++-Item 4: GUI for interactive backup
-++++++-Item 2: Job Data Spooling.
-++++++- Done: Regular expression matching.
-++++++-Item 10: New daemon communication protocol (this has been dropped).
-+++++++Items completed for release 1.38.0 -- see kernsdone
-++++++Index: patches/1.38.1-to-1.38.2.patch
-++++++===================================================================
-++++++RCS file: patches/1.38.1-to-1.38.2.patch
-++++++diff -N patches/1.38.1-to-1.38.2.patch
-++++++--- /dev/null 1 Jan 1970 00:00:00 -0000
-+++++++++ patches/1.38.1-to-1.38.2.patch 21 Nov 2005 13:06:37 -0000
-++++++@@ -0,0 +1,412 @@
-+++++++
-+++++++ This patch fixes the following bugs:
-+++++++
-+++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+++++++ says that this patch does not fix his problem)
-+++++++- Fix cancel failure bug. Bug #481
-+++++++- Fix failure when Pool name has spaces. Bug #487
-+++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++++- Fix a couple of free()s in src/filed/acl.c
-+++++++- Fix memory overrun in bfile.c in building OS X resource
-+++++++ fork filename. Bug #489
-+++++++
-+++++++This patch is applied to Bacula source version 1.38.1 and will
-+++++++produce Bacula source version 1.38.2. Apply it with:
-+++++++
-+++++++ cd <bacula-1.38.1-source>
-+++++++ ./configure (your options) if not already done
-+++++++ patch -p0 <1.38.1-to-1.38.2.patch
-+++++++ make
-+++++++ make install
-+++++++
-+++++++Index: kes-1.38
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/kes-1.38,v
-+++++++retrieving revision 1.1.2.13
-+++++++diff -u -r1.1.2.13 kes-1.38
-+++++++--- kes-1.38 14 Nov 2005 20:20:38 -0000 1.1.2.13
-++++++++++ kes-1.38 21 Nov 2005 12:53:36 -0000
-+++++++@@ -3,6 +3,17 @@
-+++++++
-+++++++ General:
-+++++++
-++++++++Changes after release of 1.38.1:
-++++++++20Oct05
-++++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++++++- Fix bnet-server bug found on OpenBSD. Bug #486
-++++++++- Fix cancel failure bug. Bug #481
-++++++++- Fix failure when Pool name has spaces. Bug #487
-++++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++++++- Fix a couple of free()s in src/filed/acl.c
-++++++++- Fix memory overrun in bfile.c in building OS X resource
-++++++++ fork filename. Bug #489
-++++++++
-+++++++ Changes to 1.38.1:
-+++++++ 14Oct05
-+++++++ - Apply SunOS patch for ACLs submitted by David Duchscher.
-+++++++Index: src/version.h
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/version.h,v
-+++++++retrieving revision 1.554.2.14
-+++++++diff -u -r1.554.2.14 version.h
-+++++++--- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-++++++++++ src/version.h 21 Nov 2005 12:53:37 -0000
-+++++++@@ -3,9 +3,9 @@
-+++++++ */
-+++++++
-+++++++ #undef VERSION
-+++++++-#define VERSION "1.38.1"
-+++++++-#define BDATE "14 November 2005"
-+++++++-#define LSMDATE "14Nov05"
-++++++++#define VERSION "1.38.2"
-++++++++#define BDATE "20 November 2005"
-++++++++#define LSMDATE "20Nov05"
-+++++++
-+++++++ /* Debug flags */
-+++++++ #undef DEBUG
-+++++++Index: src/dird/catreq.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-+++++++retrieving revision 1.77.2.1
-+++++++diff -u -r1.77.2.1 catreq.c
-+++++++--- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-++++++++++ src/dird/catreq.c 21 Nov 2005 12:53:37 -0000
-+++++++@@ -10,7 +10,7 @@
-+++++++ * Basic tasks done here:
-+++++++ * Handle Catalog services.
-+++++++ *
-+++++++- * Version $Id$
-++++++++ * Version $Id$
-+++++++ */
-+++++++ /*
-+++++++ Copyright (C) 2001-2005 Kern Sibbald
-+++++++@@ -117,6 +117,7 @@
-+++++++ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
-+++++++ memset(&pr, 0, sizeof(pr));
-+++++++ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-++++++++ unbash_spaces(pr.Name);
-+++++++ ok = db_get_pool_record(jcr, jcr->db, &pr);
-+++++++ if (ok) {
-+++++++ mr.PoolId = pr.PoolId;
-+++++++Index: src/dird/ua_restore.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-+++++++retrieving revision 1.101.2.1
-+++++++diff -u -r1.101.2.1 ua_restore.c
-+++++++--- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-++++++++++ src/dird/ua_restore.c 21 Nov 2005 12:53:37 -0000
-+++++++@@ -10,7 +10,7 @@
-+++++++ *
-+++++++ * Kern Sibbald, July MMII
-+++++++ *
-+++++++- * Version $Id$
-++++++++ * Version $Id$
-+++++++ */
-+++++++ /*
-+++++++ Copyright (C) 2002-2005 Kern Sibbald
-+++++++@@ -573,6 +573,7 @@
-+++++++ }
-+++++++ return 2;
-+++++++
-++++++++ case -2: /* Period entered to cancel */
-+++++++ case 11: /* Cancel or quit */
-+++++++ return 0;
-+++++++ }
-+++++++Index: src/dird/ua_run.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-+++++++retrieving revision 1.71
-+++++++diff -u -r1.71 ua_run.c
-+++++++--- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-++++++++++ src/dird/ua_run.c 21 Nov 2005 12:53:38 -0000
-+++++++@@ -851,6 +851,8 @@
-+++++++ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
-+++++++ }
-+++++++ goto try_again;
-++++++++ case -1: /* error or cancel */
-++++++++ goto bail_out;
-+++++++ default:
-+++++++ goto try_again;
-+++++++ }
-+++++++Index: src/dird/ua_select.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-+++++++retrieving revision 1.65.2.1
-+++++++diff -u -r1.65.2.1 ua_select.c
-+++++++--- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-++++++++++ src/dird/ua_select.c 21 Nov 2005 12:53:39 -0000
-+++++++@@ -4,7 +4,7 @@
-+++++++ *
-+++++++ * Kern Sibbald, October MMI
-+++++++ *
-+++++++- * Version $Id$
-++++++++ * Version $Id$
-+++++++ */
-+++++++ /*
-+++++++ Copyright (C) 2001-2005 Kern Sibbald
-+++++++@@ -149,7 +149,9 @@
-+++++++ }
-+++++++ }
-+++++++ UnlockRes();
-+++++++- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-++++++++ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-++++++++ return NULL;
-++++++++ }
-+++++++ store = (STORE *)GetResWithName(R_STORAGE, name);
-+++++++ return store;
-+++++++ }
-+++++++@@ -170,7 +172,9 @@
-+++++++ }
-+++++++ }
-+++++++ UnlockRes();
-+++++++- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-++++++++ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-++++++++ return NULL;
-++++++++ }
-+++++++ fs = (FILESET *)GetResWithName(R_FILESET, name);
-+++++++ return fs;
-+++++++ }
-+++++++@@ -202,7 +206,9 @@
-+++++++ }
-+++++++ }
-+++++++ UnlockRes();
-+++++++- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-++++++++ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-++++++++ return NULL;
-++++++++ }
-+++++++ catalog = (CAT *)GetResWithName(R_CATALOG, name);
-+++++++ }
-+++++++ return catalog;
-+++++++@@ -225,7 +231,9 @@
-+++++++ }
-+++++++ }
-+++++++ UnlockRes();
-+++++++- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-++++++++ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-++++++++ return NULL;
-++++++++ }
-+++++++ job = (JOB *)GetResWithName(R_JOB, name);
-+++++++ return job;
-+++++++ }
-+++++++@@ -246,7 +254,9 @@
-+++++++ }
-+++++++ }
-+++++++ UnlockRes();
-+++++++- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-++++++++ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-++++++++ return NULL;
-++++++++ }
-+++++++ job = (JOB *)GetResWithName(R_JOB, name);
-+++++++ return job;
-+++++++ }
-+++++++@@ -269,7 +279,9 @@
-+++++++ }
-+++++++ }
-+++++++ UnlockRes();
-+++++++- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-++++++++ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-++++++++ return NULL;
-++++++++ }
-+++++++ client = (CLIENT *)GetResWithName(R_CLIENT, name);
-+++++++ return client;
-+++++++ }
-+++++++@@ -551,7 +563,9 @@
-+++++++ }
-+++++++ }
-+++++++ UnlockRes();
-+++++++- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-++++++++ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-++++++++ return NULL;
-++++++++ }
-+++++++ pool = (POOL *)GetResWithName(R_POOL, name);
-+++++++ return pool;
-+++++++ }
-+++++++@@ -673,12 +687,16 @@
-+++++++ * Returns: -1 on error
-+++++++ * index base 0 on success, and choice
-+++++++ * is copied to prompt if not NULL
-++++++++ * prompt is set to the chosen prompt item string
-+++++++ */
-+++++++ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
-+++++++ {
-+++++++ int i, item;
-+++++++ char pmsg[MAXSTRING];
-+++++++
-++++++++ if (prompt) {
-++++++++ *prompt = 0;
-++++++++ }
-+++++++ if (ua->num_prompts == 2) {
-+++++++ item = 1;
-+++++++ if (prompt) {
-+++++++@@ -698,15 +716,11 @@
-+++++++ bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
-+++++++ }
-+++++++
-+++++++- if (prompt) {
-+++++++- *prompt = 0;
-+++++++- }
-+++++++-
-+++++++ for ( ;; ) {
-+++++++ /* First item is the prompt string, not the items */
-+++++++ if (ua->num_prompts == 1) {
-+++++++ bsendmsg(ua, _("Selection is empty!\n"));
-+++++++- item = 0; /* list is empty ! */
-++++++++ item = -1; /* list is empty ! */
-+++++++ break;
-+++++++ }
-+++++++ if (ua->num_prompts == 2) {
-+++++++@@ -741,7 +755,7 @@
-+++++++ free(ua->prompt[i]);
-+++++++ }
-+++++++ ua->num_prompts = 0;
-+++++++- return item - 1;
-++++++++ return item>0 ? item-1 : item;
-+++++++ }
-+++++++
-+++++++
-+++++++Index: src/dird/ua_update.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-+++++++retrieving revision 1.7
-+++++++diff -u -r1.7 ua_update.c
-+++++++--- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-++++++++++ src/dird/ua_update.c 21 Nov 2005 12:53:39 -0000
-+++++++@@ -590,7 +590,7 @@
-+++++++ update_all_vols_from_pool(ua);
-+++++++ return 1;
-+++++++ default: /* Done or error */
-+++++++- bsendmsg(ua, _("Selection done.\n"));
-++++++++ bsendmsg(ua, _("Selection terminated.\n"));
-+++++++ return 1;
-+++++++ }
-+++++++ }
-+++++++Index: src/filed/acl.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-+++++++retrieving revision 1.10.2.1
-+++++++diff -u -r1.10.2.1 acl.c
-+++++++--- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-++++++++++ src/filed/acl.c 21 Nov 2005 12:53:39 -0000
-+++++++@@ -26,7 +26,7 @@
-+++++++ *
-+++++++ * Written by Preben 'Peppe' Guldberg, December MMIV
-+++++++ *
-+++++++- * Version $Id$
-++++++++ * Version $Id$
-+++++++ */
-+++++++ /*
-+++++++ Copyright (C) 2004-2005 Kern Sibbald
-+++++++@@ -140,7 +140,7 @@
-+++++++
-+++++++ if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-+++++++ len = pm_strcpy(jcr->acl_text, acl_text);
-+++++++- free(acl_text);
-++++++++ actuallyfree(acl_text);
-+++++++ return len;
-+++++++ }
-+++++++ return -1;
-+++++++@@ -270,7 +270,7 @@
-+++++++ if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
-+++++++ if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-+++++++ len = pm_strcpy(jcr->acl_text, acl_text);
-+++++++- free(acl_text);
-++++++++ actuallyfree(acl_text);
-+++++++ return len;
-+++++++ }
-+++++++ }
-+++++++Index: src/findlib/bfile.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-+++++++retrieving revision 1.40
-+++++++diff -u -r1.40 bfile.c
-+++++++--- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-++++++++++ src/findlib/bfile.c 21 Nov 2005 12:53:39 -0000
-+++++++@@ -623,13 +623,10 @@
-+++++++ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
-+++++++ {
-+++++++ POOLMEM *rsrc_fname;
-+++++++- size_t fname_len;
-+++++++
-+++++++- fname_len = strlen(fname);
-+++++++ rsrc_fname = get_pool_memory(PM_FNAME);
-+++++++- bstrncpy(rsrc_fname, fname, fname_len + 1);
-+++++++- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-+++++++- strlen(_PATH_RSRCFORKSPEC) + 1);
-++++++++ pm_strcpy(rsrc_fname, fname);
-++++++++ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
-+++++++ bopen(bfd, rsrc_fname, flags, mode);
-+++++++ free_pool_memory(rsrc_fname);
-+++++++ return bfd->fid;
-+++++++Index: src/lib/bnet_server.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-+++++++retrieving revision 1.39
-+++++++diff -u -r1.39 bnet_server.c
-+++++++--- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-++++++++++ src/lib/bnet_server.c 21 Nov 2005 12:53:39 -0000
-+++++++@@ -153,7 +153,6 @@
-+++++++ /* Error, get out */
-+++++++ foreach_dlist(fd_ptr, &sockfds) {
-+++++++ close(fd_ptr->fd);
-+++++++- free((void *)fd_ptr);
-+++++++ }
-+++++++ Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
-+++++++ break;
-+++++++Index: src/stored/autochanger.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-+++++++retrieving revision 1.47.2.3
-+++++++diff -u -r1.47.2.3 autochanger.c
-+++++++--- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-++++++++++ src/stored/autochanger.c 21 Nov 2005 12:53:39 -0000
-+++++++@@ -4,7 +4,7 @@
-+++++++ *
-+++++++ * Kern Sibbald, August MMII
-+++++++ *
-+++++++- * Version $Id$
-++++++++ * Version $Id$
-+++++++ */
-+++++++ /*
-+++++++ Copyright (C) 2002-2005 Kern Sibbald
-+++++++@@ -163,6 +163,7 @@
-+++++++ rtn_stat = -1; /* hard error */
-+++++++ }
-+++++++ Dmsg2(400, "load slot %d status=%d\n", slot, status);
-++++++++ unlock_changer(dcr);
-+++++++ } else {
-+++++++ status = 0; /* we got what we want */
-+++++++ dev->Slot = slot; /* set currently loaded slot */
-+++++++@@ -174,7 +175,6 @@
-+++++++ } else {
-+++++++ rtn_stat = 0; /* no changer found */
-+++++++ }
-+++++++- unlock_changer(dcr);
-+++++++ free_pool_memory(changer);
-+++++++ return rtn_stat;
-+++++++
-+++++++Index: src/tray-monitor/tray-monitor.c
-+++++++===================================================================
-+++++++RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-+++++++retrieving revision 1.25.2.1
-+++++++diff -u -r1.25.2.1 tray-monitor.c
-+++++++--- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-++++++++++ src/tray-monitor/tray-monitor.c 21 Nov 2005 12:53:39 -0000
-+++++++@@ -4,7 +4,7 @@
-+++++++ *
-+++++++ * Nicolas Boichat, August MMIV
-+++++++ *
-+++++++- * Version $Id$
-++++++++ * Version $Id$
-+++++++ */
-+++++++
-+++++++ /*
-+++++++@@ -881,7 +881,7 @@
-+++++++ }
-+++++++
-+++++++ if (item->D_sock == NULL) {
-+++++++- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-++++++++ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
-+++++++ changeStatusMessage(item, _("Cannot connect to daemon."));
-+++++++ item->state = error;
-+++++++ item->oldstate = error;
-++++++Index: patches/patches-1.38.0
-++++++===================================================================
-++++++RCS file: patches/patches-1.38.0
-++++++diff -N patches/patches-1.38.0
-++++++Index: patches/patches-1.38.1
-++++++===================================================================
-++++++RCS file: patches/patches-1.38.1
-++++++diff -N patches/patches-1.38.1
-++++++--- /dev/null 1 Jan 1970 00:00:00 -0000
-+++++++++ patches/patches-1.38.1 21 Nov 2005 13:06:37 -0000
-++++++@@ -0,0 +1,14 @@
-+++++++20Nov05 1.38.1-to-1.38.2.patch
-+++++++ This patch fixes the following bugs:
-+++++++
-+++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+++++++ says this patch does not fix his problem)
-+++++++- Fix cancel failure bug. Bug #481
-+++++++- Fix failure when Pool name has spaces. Bug #487
-+++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++++- Fix a couple of free()s in src/filed/acl.c
-+++++++- Fix memory overrun in bfile.c in building OS X resource
-+++++++ fork filename. Bug #489
-+++++++
-+++++++
-++++++Index: src/version.h
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/version.h,v
-++++++retrieving revision 1.554.2.14
-++++++diff -u -r1.554.2.14 version.h
-++++++--- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-+++++++++ src/version.h 21 Nov 2005 13:06:37 -0000
-++++++@@ -3,9 +3,9 @@
-++++++ */
-++++++
-++++++ #undef VERSION
-++++++-#define VERSION "1.38.1"
-++++++-#define BDATE "14 November 2005"
-++++++-#define LSMDATE "14Nov05"
-+++++++#define VERSION "1.38.2"
-+++++++#define BDATE "20 November 2005"
-+++++++#define LSMDATE "20Nov05"
-++++++
-++++++ /* Debug flags */
-++++++ #undef DEBUG
-++++++Index: src/dird/catreq.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-++++++retrieving revision 1.77.2.1
-++++++diff -u -r1.77.2.1 catreq.c
-++++++--- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-+++++++++ src/dird/catreq.c 21 Nov 2005 13:06:37 -0000
-++++++@@ -10,7 +10,7 @@
-++++++ * Basic tasks done here:
-++++++ * Handle Catalog services.
-++++++ *
-++++++- * Version $Id$
-+++++++ * Version $Id$
-++++++ */
-++++++ /*
-++++++ Copyright (C) 2001-2005 Kern Sibbald
-++++++@@ -117,6 +117,7 @@
-++++++ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
-++++++ memset(&pr, 0, sizeof(pr));
-++++++ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-+++++++ unbash_spaces(pr.Name);
-++++++ ok = db_get_pool_record(jcr, jcr->db, &pr);
-++++++ if (ok) {
-++++++ mr.PoolId = pr.PoolId;
-++++++Index: src/dird/ua_restore.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-++++++retrieving revision 1.101.2.1
-++++++diff -u -r1.101.2.1 ua_restore.c
-++++++--- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-+++++++++ src/dird/ua_restore.c 21 Nov 2005 13:06:37 -0000
-++++++@@ -10,7 +10,7 @@
-++++++ *
-++++++ * Kern Sibbald, July MMII
-++++++ *
-++++++- * Version $Id$
-+++++++ * Version $Id$
-++++++ */
-++++++ /*
-++++++ Copyright (C) 2002-2005 Kern Sibbald
-++++++@@ -573,6 +573,7 @@
-++++++ }
-++++++ return 2;
-++++++
-+++++++ case -2: /* Period entered to cancel */
-++++++ case 11: /* Cancel or quit */
-++++++ return 0;
-++++++ }
-++++++Index: src/dird/ua_run.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-++++++retrieving revision 1.71
-++++++diff -u -r1.71 ua_run.c
-++++++--- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-+++++++++ src/dird/ua_run.c 21 Nov 2005 13:06:38 -0000
-++++++@@ -851,6 +851,8 @@
-++++++ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
-++++++ }
-++++++ goto try_again;
-+++++++ case -1: /* error or cancel */
-+++++++ goto bail_out;
-++++++ default:
-++++++ goto try_again;
-++++++ }
-++++++Index: src/dird/ua_select.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-++++++retrieving revision 1.65.2.1
-++++++diff -u -r1.65.2.1 ua_select.c
-++++++--- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-+++++++++ src/dird/ua_select.c 21 Nov 2005 13:06:38 -0000
-++++++@@ -4,7 +4,7 @@
-++++++ *
-++++++ * Kern Sibbald, October MMI
-++++++ *
-++++++- * Version $Id$
-+++++++ * Version $Id$
-++++++ */
-++++++ /*
-++++++ Copyright (C) 2001-2005 Kern Sibbald
-++++++@@ -149,7 +149,9 @@
-++++++ }
-++++++ }
-++++++ UnlockRes();
-++++++- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-+++++++ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-+++++++ return NULL;
-+++++++ }
-++++++ store = (STORE *)GetResWithName(R_STORAGE, name);
-++++++ return store;
-++++++ }
-++++++@@ -170,7 +172,9 @@
-++++++ }
-++++++ }
-++++++ UnlockRes();
-++++++- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-+++++++ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-+++++++ return NULL;
-+++++++ }
-++++++ fs = (FILESET *)GetResWithName(R_FILESET, name);
-++++++ return fs;
-++++++ }
-++++++@@ -202,7 +206,9 @@
-++++++ }
-++++++ }
-++++++ UnlockRes();
-++++++- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-+++++++ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-+++++++ return NULL;
-+++++++ }
-++++++ catalog = (CAT *)GetResWithName(R_CATALOG, name);
-++++++ }
-++++++ return catalog;
-++++++@@ -225,7 +231,9 @@
-++++++ }
-++++++ }
-++++++ UnlockRes();
-++++++- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-+++++++ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-+++++++ return NULL;
-+++++++ }
-++++++ job = (JOB *)GetResWithName(R_JOB, name);
-++++++ return job;
-++++++ }
-++++++@@ -246,7 +254,9 @@
-++++++ }
-++++++ }
-++++++ UnlockRes();
-++++++- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-+++++++ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-+++++++ return NULL;
-+++++++ }
-++++++ job = (JOB *)GetResWithName(R_JOB, name);
-++++++ return job;
-++++++ }
-++++++@@ -269,7 +279,9 @@
-++++++ }
-++++++ }
-++++++ UnlockRes();
-++++++- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-+++++++ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-+++++++ return NULL;
-+++++++ }
-++++++ client = (CLIENT *)GetResWithName(R_CLIENT, name);
-++++++ return client;
-++++++ }
-++++++@@ -551,7 +563,9 @@
-++++++ }
-++++++ }
-++++++ UnlockRes();
-++++++- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-+++++++ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-+++++++ return NULL;
-+++++++ }
-++++++ pool = (POOL *)GetResWithName(R_POOL, name);
-++++++ return pool;
-++++++ }
-++++++@@ -673,12 +687,16 @@
-++++++ * Returns: -1 on error
-++++++ * index base 0 on success, and choice
-++++++ * is copied to prompt if not NULL
-+++++++ * prompt is set to the chosen prompt item string
-++++++ */
-++++++ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
-++++++ {
-++++++ int i, item;
-++++++ char pmsg[MAXSTRING];
-++++++
-+++++++ if (prompt) {
-+++++++ *prompt = 0;
-+++++++ }
-++++++ if (ua->num_prompts == 2) {
-++++++ item = 1;
-++++++ if (prompt) {
-++++++@@ -698,15 +716,11 @@
-++++++ bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
-++++++ }
-++++++
-++++++- if (prompt) {
-++++++- *prompt = 0;
-++++++- }
-++++++-
-++++++ for ( ;; ) {
-++++++ /* First item is the prompt string, not the items */
-++++++ if (ua->num_prompts == 1) {
-++++++ bsendmsg(ua, _("Selection is empty!\n"));
-++++++- item = 0; /* list is empty ! */
-+++++++ item = -1; /* list is empty ! */
-++++++ break;
-++++++ }
-++++++ if (ua->num_prompts == 2) {
-++++++@@ -741,7 +755,7 @@
-++++++ free(ua->prompt[i]);
-++++++ }
-++++++ ua->num_prompts = 0;
-++++++- return item - 1;
-+++++++ return item>0 ? item-1 : item;
-++++++ }
-++++++
-++++++
-++++++Index: src/dird/ua_update.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-++++++retrieving revision 1.7
-++++++diff -u -r1.7 ua_update.c
-++++++--- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-+++++++++ src/dird/ua_update.c 21 Nov 2005 13:06:38 -0000
-++++++@@ -590,7 +590,7 @@
-++++++ update_all_vols_from_pool(ua);
-++++++ return 1;
-++++++ default: /* Done or error */
-++++++- bsendmsg(ua, _("Selection done.\n"));
-+++++++ bsendmsg(ua, _("Selection terminated.\n"));
-++++++ return 1;
-++++++ }
-++++++ }
-++++++Index: src/filed/acl.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-++++++retrieving revision 1.10.2.1
-++++++diff -u -r1.10.2.1 acl.c
-++++++--- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-+++++++++ src/filed/acl.c 21 Nov 2005 13:06:38 -0000
-++++++@@ -26,7 +26,7 @@
-++++++ *
-++++++ * Written by Preben 'Peppe' Guldberg, December MMIV
-++++++ *
-++++++- * Version $Id$
-+++++++ * Version $Id$
-++++++ */
-++++++ /*
-++++++ Copyright (C) 2004-2005 Kern Sibbald
-++++++@@ -140,7 +140,7 @@
-++++++
-++++++ if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-++++++ len = pm_strcpy(jcr->acl_text, acl_text);
-++++++- free(acl_text);
-+++++++ actuallyfree(acl_text);
-++++++ return len;
-++++++ }
-++++++ return -1;
-++++++@@ -270,7 +270,7 @@
-++++++ if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
-++++++ if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-++++++ len = pm_strcpy(jcr->acl_text, acl_text);
-++++++- free(acl_text);
-+++++++ actuallyfree(acl_text);
-++++++ return len;
-++++++ }
-++++++ }
-++++++Index: src/findlib/bfile.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-++++++retrieving revision 1.40
-++++++diff -u -r1.40 bfile.c
-++++++--- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-+++++++++ src/findlib/bfile.c 21 Nov 2005 13:06:38 -0000
-++++++@@ -623,13 +623,10 @@
-++++++ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
-++++++ {
-++++++ POOLMEM *rsrc_fname;
-++++++- size_t fname_len;
-++++++
-++++++- fname_len = strlen(fname);
-++++++ rsrc_fname = get_pool_memory(PM_FNAME);
-++++++- bstrncpy(rsrc_fname, fname, fname_len + 1);
-++++++- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-++++++- strlen(_PATH_RSRCFORKSPEC) + 1);
-+++++++ pm_strcpy(rsrc_fname, fname);
-+++++++ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
-++++++ bopen(bfd, rsrc_fname, flags, mode);
-++++++ free_pool_memory(rsrc_fname);
-++++++ return bfd->fid;
-++++++Index: src/lib/bnet_server.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-++++++retrieving revision 1.39
-++++++diff -u -r1.39 bnet_server.c
-++++++--- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-+++++++++ src/lib/bnet_server.c 21 Nov 2005 13:06:38 -0000
-++++++@@ -153,7 +153,6 @@
-++++++ /* Error, get out */
-++++++ foreach_dlist(fd_ptr, &sockfds) {
-++++++ close(fd_ptr->fd);
-++++++- free((void *)fd_ptr);
-++++++ }
-++++++ Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
-++++++ break;
-++++++Index: src/stored/autochanger.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-++++++retrieving revision 1.47.2.3
-++++++diff -u -r1.47.2.3 autochanger.c
-++++++--- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-+++++++++ src/stored/autochanger.c 21 Nov 2005 13:06:38 -0000
-++++++@@ -4,7 +4,7 @@
-++++++ *
-++++++ * Kern Sibbald, August MMII
-++++++ *
-++++++- * Version $Id$
-+++++++ * Version $Id$
-++++++ */
-++++++ /*
-++++++ Copyright (C) 2002-2005 Kern Sibbald
-++++++@@ -163,6 +163,7 @@
-++++++ rtn_stat = -1; /* hard error */
-++++++ }
-++++++ Dmsg2(400, "load slot %d status=%d\n", slot, status);
-+++++++ unlock_changer(dcr);
-++++++ } else {
-++++++ status = 0; /* we got what we want */
-++++++ dev->Slot = slot; /* set currently loaded slot */
-++++++@@ -174,7 +175,6 @@
-++++++ } else {
-++++++ rtn_stat = 0; /* no changer found */
-++++++ }
-++++++- unlock_changer(dcr);
-++++++ free_pool_memory(changer);
-++++++ return rtn_stat;
-++++++
-++++++Index: src/stored/status.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/stored/status.c,v
-++++++retrieving revision 1.44.2.1
-++++++diff -u -r1.44.2.1 status.c
-++++++--- src/stored/status.c 6 Oct 2005 07:04:13 -0000 1.44.2.1
-+++++++++ src/stored/status.c 21 Nov 2005 13:06:39 -0000
-++++++@@ -264,6 +264,7 @@
-++++++ bool found = false;
-++++++ int bps, sec;
-++++++ JCR *jcr;
-+++++++ DCR *dcr;
-++++++ char JobName[MAX_NAME_LENGTH];
-++++++ char b1[30], b2[30], b3[30];
-++++++
-++++++@@ -273,7 +274,8 @@
-++++++ bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
-++++++ job_type_to_str(jcr->JobType), jcr->Job);
-++++++ }
-++++++- if (jcr->dcr && jcr->dcr->device) {
-+++++++ dcr = jcr->dcr;
-+++++++ if (dcr && dcr->device) {
-++++++ bstrncpy(JobName, jcr->Job, sizeof(JobName));
-++++++ /* There are three periods after the Job name */
-++++++ char *p;
-++++++@@ -282,13 +284,16 @@
-++++++ *p = 0;
-++++++ }
-++++++ }
-++++++- bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\" device=\"%s\"\n"),
-+++++++ bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\"\n"
-+++++++ " pool=\"%s\" device=\"%s\"\n"),
-++++++ job_level_to_str(jcr->JobLevel),
-++++++ job_type_to_str(jcr->JobType),
-++++++ JobName,
-++++++ jcr->JobId,
-++++++- jcr->dcr->VolumeName,
-++++++- jcr->dcr->device->device_name);
-+++++++ dcr->VolumeName,
-+++++++ dcr->pool_name,
-+++++++ dcr->dev?dcr->dev->print_name():
-+++++++ dcr->device->device_name);
-++++++ sec = time(NULL) - jcr->run_time;
-++++++ if (sec <= 0) {
-++++++ sec = 1;
-++++++Index: src/stored/stored_conf.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/stored/stored_conf.c,v
-++++++retrieving revision 1.76
-++++++diff -u -r1.76 stored_conf.c
-++++++--- src/stored/stored_conf.c 9 Sep 2005 09:40:04 -0000 1.76
-+++++++++ src/stored/stored_conf.c 21 Nov 2005 13:06:39 -0000
-++++++@@ -222,16 +222,16 @@
-++++++ res->res_dev.hdr.name,
-++++++ res->res_dev.media_type, res->res_dev.device_name,
-++++++ res->res_dev.label_type);
-++++++- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
-+++++++ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d chgr_wait=%d\n",
-++++++ res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-++++++- res->res_dev.max_block_size);
-+++++++ res->res_dev.max_block_size, res->res_dev.max_changer_wait);
-++++++ sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-++++++ res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-++++++ res->res_dev.max_volume_size);
-++++++ sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
-++++++ res->res_dev.max_file_size, res->res_dev.volume_capacity);
-++++++- sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-++++++- sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-+++++++ sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-+++++++ sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-++++++ res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
-++++++ if (res->res_dev.changer_res) {
-++++++ sendit(sock, " changer=%p\n", res->res_dev.changer_res);
-++++++Index: src/tray-monitor/tray-monitor.c
-++++++===================================================================
-++++++RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-++++++retrieving revision 1.25.2.1
-++++++diff -u -r1.25.2.1 tray-monitor.c
-++++++--- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-+++++++++ src/tray-monitor/tray-monitor.c 21 Nov 2005 13:06:39 -0000
-++++++@@ -4,7 +4,7 @@
-++++++ *
-++++++ * Nicolas Boichat, August MMIV
-++++++ *
-++++++- * Version $Id$
-+++++++ * Version $Id$
-++++++ */
-++++++
-++++++ /*
-++++++@@ -881,7 +881,7 @@
-++++++ }
-++++++
-++++++ if (item->D_sock == NULL) {
-++++++- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-+++++++ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
-++++++ changeStatusMessage(item, _("Cannot connect to daemon."));
-++++++ item->state = error;
-++++++ item->oldstate = error;
-+++++Index: patches/patches-1.38.0
-+++++===================================================================
-+++++RCS file: patches/patches-1.38.0
-+++++diff -N patches/patches-1.38.0
-+++++Index: patches/patches-1.38.1
-+++++===================================================================
-+++++RCS file: patches/patches-1.38.1
-+++++diff -N patches/patches-1.38.1
-+++++--- /dev/null 1 Jan 1970 00:00:00 -0000
-++++++++ patches/patches-1.38.1 21 Nov 2005 13:13:01 -0000
-+++++@@ -0,0 +1,14 @@
-++++++20Nov05 1.38.1-to-1.38.2.patch
-++++++ This patch fixes the following bugs:
-++++++
-++++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++++++ says this patch does not fix his problem)
-++++++- Fix cancel failure bug. Bug #481
-++++++- Fix failure when Pool name has spaces. Bug #487
-++++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++++- Fix a couple of free()s in src/filed/acl.c
-++++++- Fix memory overrun in bfile.c in building OS X resource
-++++++ fork filename. Bug #489
-++++++
-++++++
-+++++Index: src/version.h
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/version.h,v
-+++++retrieving revision 1.554.2.14
-+++++diff -u -r1.554.2.14 version.h
-+++++--- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-++++++++ src/version.h 21 Nov 2005 13:13:01 -0000
-+++++@@ -3,9 +3,9 @@
-+++++ */
-+++++
-+++++ #undef VERSION
-+++++-#define VERSION "1.38.1"
-+++++-#define BDATE "14 November 2005"
-+++++-#define LSMDATE "14Nov05"
-++++++#define VERSION "1.38.2"
-++++++#define BDATE "20 November 2005"
-++++++#define LSMDATE "20Nov05"
-+++++
-+++++ /* Debug flags */
-+++++ #undef DEBUG
-+++++Index: src/dird/catreq.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-+++++retrieving revision 1.77.2.1
-+++++diff -u -r1.77.2.1 catreq.c
-+++++--- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-++++++++ src/dird/catreq.c 21 Nov 2005 13:13:01 -0000
-+++++@@ -10,7 +10,7 @@
-+++++ * Basic tasks done here:
-+++++ * Handle Catalog services.
-+++++ *
-+++++- * Version $Id$
-++++++ * Version $Id$
-+++++ */
-+++++ /*
-+++++ Copyright (C) 2001-2005 Kern Sibbald
-+++++@@ -117,6 +117,7 @@
-+++++ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
-+++++ memset(&pr, 0, sizeof(pr));
-+++++ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-++++++ unbash_spaces(pr.Name);
-+++++ ok = db_get_pool_record(jcr, jcr->db, &pr);
-+++++ if (ok) {
-+++++ mr.PoolId = pr.PoolId;
-+++++Index: src/dird/ua_restore.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-+++++retrieving revision 1.101.2.1
-+++++diff -u -r1.101.2.1 ua_restore.c
-+++++--- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-++++++++ src/dird/ua_restore.c 21 Nov 2005 13:13:01 -0000
-+++++@@ -10,7 +10,7 @@
-+++++ *
-+++++ * Kern Sibbald, July MMII
-+++++ *
-+++++- * Version $Id$
-++++++ * Version $Id$
-+++++ */
-+++++ /*
-+++++ Copyright (C) 2002-2005 Kern Sibbald
-+++++@@ -409,7 +409,7 @@
-+++++ }
-+++++ done = true;
-+++++ switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
-+++++- case -1: /* error */
-++++++ case -1: /* error or cancel */
-+++++ return 0;
-+++++ case 0: /* list last 20 Jobs run */
-+++++ gui_save = ua->jcr->gui;
-+++++Index: src/dird/ua_run.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-+++++retrieving revision 1.71
-+++++diff -u -r1.71 ua_run.c
-+++++--- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-++++++++ src/dird/ua_run.c 21 Nov 2005 13:13:02 -0000
-+++++@@ -851,6 +851,8 @@
-+++++ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
-+++++ }
-+++++ goto try_again;
-++++++ case -1: /* error or cancel */
-++++++ goto bail_out;
-+++++ default:
-+++++ goto try_again;
-+++++ }
-+++++Index: src/dird/ua_select.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-+++++retrieving revision 1.65.2.1
-+++++diff -u -r1.65.2.1 ua_select.c
-+++++--- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-++++++++ src/dird/ua_select.c 21 Nov 2005 13:13:02 -0000
-+++++@@ -4,7 +4,7 @@
-+++++ *
-+++++ * Kern Sibbald, October MMI
-+++++ *
-+++++- * Version $Id$
-++++++ * Version $Id$
-+++++ */
-+++++ /*
-+++++ Copyright (C) 2001-2005 Kern Sibbald
-+++++@@ -149,7 +149,9 @@
-+++++ }
-+++++ }
-+++++ UnlockRes();
-+++++- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-++++++ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-++++++ return NULL;
-++++++ }
-+++++ store = (STORE *)GetResWithName(R_STORAGE, name);
-+++++ return store;
-+++++ }
-+++++@@ -170,7 +172,9 @@
-+++++ }
-+++++ }
-+++++ UnlockRes();
-+++++- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-++++++ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-++++++ return NULL;
-++++++ }
-+++++ fs = (FILESET *)GetResWithName(R_FILESET, name);
-+++++ return fs;
-+++++ }
-+++++@@ -202,7 +206,9 @@
-+++++ }
-+++++ }
-+++++ UnlockRes();
-+++++- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-++++++ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-++++++ return NULL;
-++++++ }
-+++++ catalog = (CAT *)GetResWithName(R_CATALOG, name);
-+++++ }
-+++++ return catalog;
-+++++@@ -225,7 +231,9 @@
-+++++ }
-+++++ }
-+++++ UnlockRes();
-+++++- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-++++++ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-++++++ return NULL;
-++++++ }
-+++++ job = (JOB *)GetResWithName(R_JOB, name);
-+++++ return job;
-+++++ }
-+++++@@ -246,7 +254,9 @@
-+++++ }
-+++++ }
-+++++ UnlockRes();
-+++++- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-++++++ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-++++++ return NULL;
-++++++ }
-+++++ job = (JOB *)GetResWithName(R_JOB, name);
-+++++ return job;
-+++++ }
-+++++@@ -269,7 +279,9 @@
-+++++ }
-+++++ }
-+++++ UnlockRes();
-+++++- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-++++++ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-++++++ return NULL;
-++++++ }
-+++++ client = (CLIENT *)GetResWithName(R_CLIENT, name);
-+++++ return client;
-+++++ }
-+++++@@ -551,7 +563,9 @@
-+++++ }
-+++++ }
-+++++ UnlockRes();
-+++++- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-++++++ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-++++++ return NULL;
-++++++ }
-+++++ pool = (POOL *)GetResWithName(R_POOL, name);
-+++++ return pool;
-+++++ }
-+++++@@ -673,12 +687,16 @@
-+++++ * Returns: -1 on error
-+++++ * index base 0 on success, and choice
-+++++ * is copied to prompt if not NULL
-++++++ * prompt is set to the chosen prompt item string
-+++++ */
-+++++ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
-+++++ {
-+++++ int i, item;
-+++++ char pmsg[MAXSTRING];
-+++++
-++++++ if (prompt) {
-++++++ *prompt = 0;
-++++++ }
-+++++ if (ua->num_prompts == 2) {
-+++++ item = 1;
-+++++ if (prompt) {
-+++++@@ -698,15 +716,11 @@
-+++++ bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
-+++++ }
-+++++
-+++++- if (prompt) {
-+++++- *prompt = 0;
-+++++- }
-+++++-
-+++++ for ( ;; ) {
-+++++ /* First item is the prompt string, not the items */
-+++++ if (ua->num_prompts == 1) {
-+++++ bsendmsg(ua, _("Selection is empty!\n"));
-+++++- item = 0; /* list is empty ! */
-++++++ item = -1; /* list is empty ! */
-+++++ break;
-+++++ }
-+++++ if (ua->num_prompts == 2) {
-+++++@@ -741,7 +755,7 @@
-+++++ free(ua->prompt[i]);
-+++++ }
-+++++ ua->num_prompts = 0;
-+++++- return item - 1;
-++++++ return item>0 ? item-1 : item;
-+++++ }
-+++++
-+++++
-+++++Index: src/dird/ua_update.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-+++++retrieving revision 1.7
-+++++diff -u -r1.7 ua_update.c
-+++++--- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-++++++++ src/dird/ua_update.c 21 Nov 2005 13:13:02 -0000
-+++++@@ -590,7 +590,7 @@
-+++++ update_all_vols_from_pool(ua);
-+++++ return 1;
-+++++ default: /* Done or error */
-+++++- bsendmsg(ua, _("Selection done.\n"));
-++++++ bsendmsg(ua, _("Selection terminated.\n"));
-+++++ return 1;
-+++++ }
-+++++ }
-+++++Index: src/filed/acl.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-+++++retrieving revision 1.10.2.1
-+++++diff -u -r1.10.2.1 acl.c
-+++++--- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-++++++++ src/filed/acl.c 21 Nov 2005 13:13:02 -0000
-+++++@@ -26,7 +26,7 @@
-+++++ *
-+++++ * Written by Preben 'Peppe' Guldberg, December MMIV
-+++++ *
-+++++- * Version $Id$
-++++++ * Version $Id$
-+++++ */
-+++++ /*
-+++++ Copyright (C) 2004-2005 Kern Sibbald
-+++++@@ -140,7 +140,7 @@
-+++++
-+++++ if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-+++++ len = pm_strcpy(jcr->acl_text, acl_text);
-+++++- free(acl_text);
-++++++ actuallyfree(acl_text);
-+++++ return len;
-+++++ }
-+++++ return -1;
-+++++@@ -270,7 +270,7 @@
-+++++ if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
-+++++ if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-+++++ len = pm_strcpy(jcr->acl_text, acl_text);
-+++++- free(acl_text);
-++++++ actuallyfree(acl_text);
-+++++ return len;
-+++++ }
-+++++ }
-+++++Index: src/findlib/bfile.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-+++++retrieving revision 1.40
-+++++diff -u -r1.40 bfile.c
-+++++--- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-++++++++ src/findlib/bfile.c 21 Nov 2005 13:13:02 -0000
-+++++@@ -623,13 +623,10 @@
-+++++ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
-+++++ {
-+++++ POOLMEM *rsrc_fname;
-+++++- size_t fname_len;
-+++++
-+++++- fname_len = strlen(fname);
-+++++ rsrc_fname = get_pool_memory(PM_FNAME);
-+++++- bstrncpy(rsrc_fname, fname, fname_len + 1);
-+++++- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-+++++- strlen(_PATH_RSRCFORKSPEC) + 1);
-++++++ pm_strcpy(rsrc_fname, fname);
-++++++ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
-+++++ bopen(bfd, rsrc_fname, flags, mode);
-+++++ free_pool_memory(rsrc_fname);
-+++++ return bfd->fid;
-+++++Index: src/lib/bnet_server.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-+++++retrieving revision 1.39
-+++++diff -u -r1.39 bnet_server.c
-+++++--- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-++++++++ src/lib/bnet_server.c 21 Nov 2005 13:13:03 -0000
-+++++@@ -153,7 +153,6 @@
-+++++ /* Error, get out */
-+++++ foreach_dlist(fd_ptr, &sockfds) {
-+++++ close(fd_ptr->fd);
-+++++- free((void *)fd_ptr);
-+++++ }
-+++++ Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
-+++++ break;
-+++++Index: src/stored/autochanger.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-+++++retrieving revision 1.47.2.3
-+++++diff -u -r1.47.2.3 autochanger.c
-+++++--- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-++++++++ src/stored/autochanger.c 21 Nov 2005 13:13:03 -0000
-+++++@@ -4,7 +4,7 @@
-+++++ *
-+++++ * Kern Sibbald, August MMII
-+++++ *
-+++++- * Version $Id$
-++++++ * Version $Id$
-+++++ */
-+++++ /*
-+++++ Copyright (C) 2002-2005 Kern Sibbald
-+++++@@ -163,6 +163,7 @@
-+++++ rtn_stat = -1; /* hard error */
-+++++ }
-+++++ Dmsg2(400, "load slot %d status=%d\n", slot, status);
-++++++ unlock_changer(dcr);
-+++++ } else {
-+++++ status = 0; /* we got what we want */
-+++++ dev->Slot = slot; /* set currently loaded slot */
-+++++@@ -174,7 +175,6 @@
-+++++ } else {
-+++++ rtn_stat = 0; /* no changer found */
-+++++ }
-+++++- unlock_changer(dcr);
-+++++ free_pool_memory(changer);
-+++++ return rtn_stat;
-+++++
-+++++Index: src/stored/status.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/stored/status.c,v
-+++++retrieving revision 1.44.2.1
-+++++diff -u -r1.44.2.1 status.c
-+++++--- src/stored/status.c 6 Oct 2005 07:04:13 -0000 1.44.2.1
-++++++++ src/stored/status.c 21 Nov 2005 13:13:03 -0000
-+++++@@ -264,6 +264,7 @@
-+++++ bool found = false;
-+++++ int bps, sec;
-+++++ JCR *jcr;
-++++++ DCR *dcr;
-+++++ char JobName[MAX_NAME_LENGTH];
-+++++ char b1[30], b2[30], b3[30];
-+++++
-+++++@@ -273,7 +274,8 @@
-+++++ bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
-+++++ job_type_to_str(jcr->JobType), jcr->Job);
-+++++ }
-+++++- if (jcr->dcr && jcr->dcr->device) {
-++++++ dcr = jcr->dcr;
-++++++ if (dcr && dcr->device) {
-+++++ bstrncpy(JobName, jcr->Job, sizeof(JobName));
-+++++ /* There are three periods after the Job name */
-+++++ char *p;
-+++++@@ -282,13 +284,16 @@
-+++++ *p = 0;
-+++++ }
-+++++ }
-+++++- bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\" device=\"%s\"\n"),
-++++++ bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\"\n"
-++++++ " pool=\"%s\" device=\"%s\"\n"),
-+++++ job_level_to_str(jcr->JobLevel),
-+++++ job_type_to_str(jcr->JobType),
-+++++ JobName,
-+++++ jcr->JobId,
-+++++- jcr->dcr->VolumeName,
-+++++- jcr->dcr->device->device_name);
-++++++ dcr->VolumeName,
-++++++ dcr->pool_name,
-++++++ dcr->dev?dcr->dev->print_name():
-++++++ dcr->device->device_name);
-+++++ sec = time(NULL) - jcr->run_time;
-+++++ if (sec <= 0) {
-+++++ sec = 1;
-+++++Index: src/stored/stored_conf.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/stored/stored_conf.c,v
-+++++retrieving revision 1.76
-+++++diff -u -r1.76 stored_conf.c
-+++++--- src/stored/stored_conf.c 9 Sep 2005 09:40:04 -0000 1.76
-++++++++ src/stored/stored_conf.c 21 Nov 2005 13:13:04 -0000
-+++++@@ -222,16 +222,16 @@
-+++++ res->res_dev.hdr.name,
-+++++ res->res_dev.media_type, res->res_dev.device_name,
-+++++ res->res_dev.label_type);
-+++++- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
-++++++ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d chgr_wait=%d\n",
-+++++ res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-+++++- res->res_dev.max_block_size);
-++++++ res->res_dev.max_block_size, res->res_dev.max_changer_wait);
-+++++ sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-+++++ res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-+++++ res->res_dev.max_volume_size);
-+++++ sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
-+++++ res->res_dev.max_file_size, res->res_dev.volume_capacity);
-+++++- sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-+++++- sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-++++++ sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-++++++ sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-+++++ res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
-+++++ if (res->res_dev.changer_res) {
-+++++ sendit(sock, " changer=%p\n", res->res_dev.changer_res);
-+++++Index: src/tray-monitor/tray-monitor.c
-+++++===================================================================
-+++++RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-+++++retrieving revision 1.25.2.1
-+++++diff -u -r1.25.2.1 tray-monitor.c
-+++++--- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-++++++++ src/tray-monitor/tray-monitor.c 21 Nov 2005 13:13:04 -0000
-+++++@@ -4,7 +4,7 @@
-+++++ *
-+++++ * Nicolas Boichat, August MMIV
-+++++ *
-+++++- * Version $Id$
-++++++ * Version $Id$
-+++++ */
-+++++
-+++++ /*
-+++++@@ -881,7 +881,7 @@
-+++++ }
-+++++
-+++++ if (item->D_sock == NULL) {
-+++++- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-++++++ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
-+++++ changeStatusMessage(item, _("Cannot connect to daemon."));
-+++++ item->state = error;
-+++++ item->oldstate = error;
-++++Index: patches/patches-1.38.0
-++++===================================================================
-++++RCS file: patches/patches-1.38.0
-++++diff -N patches/patches-1.38.0
-++++Index: patches/patches-1.38.1
-++++===================================================================
-++++RCS file: patches/patches-1.38.1
-++++diff -N patches/patches-1.38.1
-++++--- /dev/null 1 Jan 1970 00:00:00 -0000
-+++++++ patches/patches-1.38.1 21 Nov 2005 13:17:58 -0000
-++++@@ -0,0 +1,14 @@
-+++++20Nov05 1.38.1-to-1.38.2.patch
-+++++ This patch fixes the following bugs:
-+++++
-+++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+++++ says this patch does not fix his problem)
-+++++- Fix cancel failure bug. Bug #481
-+++++- Fix failure when Pool name has spaces. Bug #487
-+++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++++- Fix a couple of free()s in src/filed/acl.c
-+++++- Fix memory overrun in bfile.c in building OS X resource
-+++++ fork filename. Bug #489
-+++++
-+++++
-++++Index: src/version.h
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/version.h,v
-++++retrieving revision 1.554.2.14
-++++diff -u -r1.554.2.14 version.h
-++++--- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-+++++++ src/version.h 21 Nov 2005 13:17:58 -0000
-++++@@ -3,9 +3,9 @@
-++++ */
-++++
-++++ #undef VERSION
-++++-#define VERSION "1.38.1"
-++++-#define BDATE "14 November 2005"
-++++-#define LSMDATE "14Nov05"
-+++++#define VERSION "1.38.2"
-+++++#define BDATE "20 November 2005"
-+++++#define LSMDATE "20Nov05"
-++++
-++++ /* Debug flags */
-++++ #undef DEBUG
-++++Index: src/dird/catreq.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-++++retrieving revision 1.77.2.1
-++++diff -u -r1.77.2.1 catreq.c
-++++--- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-+++++++ src/dird/catreq.c 21 Nov 2005 13:17:59 -0000
-++++@@ -10,7 +10,7 @@
-++++ * Basic tasks done here:
-++++ * Handle Catalog services.
-++++ *
-++++- * Version $Id$
-+++++ * Version $Id$
-++++ */
-++++ /*
-++++ Copyright (C) 2001-2005 Kern Sibbald
-++++@@ -117,6 +117,7 @@
-++++ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
-++++ memset(&pr, 0, sizeof(pr));
-++++ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-+++++ unbash_spaces(pr.Name);
-++++ ok = db_get_pool_record(jcr, jcr->db, &pr);
-++++ if (ok) {
-++++ mr.PoolId = pr.PoolId;
-++++Index: src/dird/ua_restore.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-++++retrieving revision 1.101.2.1
-++++diff -u -r1.101.2.1 ua_restore.c
-++++--- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-+++++++ src/dird/ua_restore.c 21 Nov 2005 13:17:59 -0000
-++++@@ -10,7 +10,7 @@
-++++ *
-++++ * Kern Sibbald, July MMII
-++++ *
-++++- * Version $Id$
-+++++ * Version $Id$
-++++ */
-++++ /*
-++++ Copyright (C) 2002-2005 Kern Sibbald
-++++@@ -409,7 +409,7 @@
-++++ }
-++++ done = true;
-++++ switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
-++++- case -1: /* error */
-+++++ case -1: /* error or cancel */
-++++ return 0;
-++++ case 0: /* list last 20 Jobs run */
-++++ gui_save = ua->jcr->gui;
-++++Index: src/dird/ua_run.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-++++retrieving revision 1.71
-++++diff -u -r1.71 ua_run.c
-++++--- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-+++++++ src/dird/ua_run.c 21 Nov 2005 13:17:59 -0000
-++++@@ -851,6 +851,8 @@
-++++ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
-++++ }
-++++ goto try_again;
-+++++ case -1: /* error or cancel */
-+++++ goto bail_out;
-++++ default:
-++++ goto try_again;
-++++ }
-++++Index: src/dird/ua_select.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-++++retrieving revision 1.65.2.1
-++++diff -u -r1.65.2.1 ua_select.c
-++++--- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-+++++++ src/dird/ua_select.c 21 Nov 2005 13:17:59 -0000
-++++@@ -4,7 +4,7 @@
-++++ *
-++++ * Kern Sibbald, October MMI
-++++ *
-++++- * Version $Id$
-+++++ * Version $Id$
-++++ */
-++++ /*
-++++ Copyright (C) 2001-2005 Kern Sibbald
-++++@@ -149,7 +149,9 @@
-++++ }
-++++ }
-++++ UnlockRes();
-++++- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-+++++ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-+++++ return NULL;
-+++++ }
-++++ store = (STORE *)GetResWithName(R_STORAGE, name);
-++++ return store;
-++++ }
-++++@@ -170,7 +172,9 @@
-++++ }
-++++ }
-++++ UnlockRes();
-++++- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-+++++ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-+++++ return NULL;
-+++++ }
-++++ fs = (FILESET *)GetResWithName(R_FILESET, name);
-++++ return fs;
-++++ }
-++++@@ -202,7 +206,9 @@
-++++ }
-++++ }
-++++ UnlockRes();
-++++- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-+++++ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-+++++ return NULL;
-+++++ }
-++++ catalog = (CAT *)GetResWithName(R_CATALOG, name);
-++++ }
-++++ return catalog;
-++++@@ -225,7 +231,9 @@
-++++ }
-++++ }
-++++ UnlockRes();
-++++- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-+++++ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-+++++ return NULL;
-+++++ }
-++++ job = (JOB *)GetResWithName(R_JOB, name);
-++++ return job;
-++++ }
-++++@@ -246,7 +254,9 @@
-++++ }
-++++ }
-++++ UnlockRes();
-++++- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-+++++ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-+++++ return NULL;
-+++++ }
-++++ job = (JOB *)GetResWithName(R_JOB, name);
-++++ return job;
-++++ }
-++++@@ -269,7 +279,9 @@
-++++ }
-++++ }
-++++ UnlockRes();
-++++- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-+++++ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-+++++ return NULL;
-+++++ }
-++++ client = (CLIENT *)GetResWithName(R_CLIENT, name);
-++++ return client;
-++++ }
-++++@@ -551,7 +563,9 @@
-++++ }
-++++ }
-++++ UnlockRes();
-++++- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-+++++ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-+++++ return NULL;
-+++++ }
-++++ pool = (POOL *)GetResWithName(R_POOL, name);
-++++ return pool;
-++++ }
-++++@@ -673,12 +687,16 @@
-++++ * Returns: -1 on error
-++++ * index base 0 on success, and choice
-++++ * is copied to prompt if not NULL
-+++++ * prompt is set to the chosen prompt item string
-++++ */
-++++ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
-++++ {
-++++ int i, item;
-++++ char pmsg[MAXSTRING];
-++++
-+++++ if (prompt) {
-+++++ *prompt = 0;
-+++++ }
-++++ if (ua->num_prompts == 2) {
-++++ item = 1;
-++++ if (prompt) {
-++++@@ -698,15 +716,11 @@
-++++ bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
-++++ }
-++++
-++++- if (prompt) {
-++++- *prompt = 0;
-++++- }
-++++-
-++++ for ( ;; ) {
-++++ /* First item is the prompt string, not the items */
-++++ if (ua->num_prompts == 1) {
-++++ bsendmsg(ua, _("Selection is empty!\n"));
-++++- item = 0; /* list is empty ! */
-+++++ item = -1; /* list is empty ! */
-++++ break;
-++++ }
-++++ if (ua->num_prompts == 2) {
-++++@@ -741,7 +755,7 @@
-++++ free(ua->prompt[i]);
-++++ }
-++++ ua->num_prompts = 0;
-++++- return item - 1;
-+++++ return item>0 ? item-1 : item;
-++++ }
-++++
-++++
-++++Index: src/dird/ua_update.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-++++retrieving revision 1.7
-++++diff -u -r1.7 ua_update.c
-++++--- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-+++++++ src/dird/ua_update.c 21 Nov 2005 13:17:59 -0000
-++++@@ -590,7 +590,7 @@
-++++ update_all_vols_from_pool(ua);
-++++ return 1;
-++++ default: /* Done or error */
-++++- bsendmsg(ua, _("Selection done.\n"));
-+++++ bsendmsg(ua, _("Selection terminated.\n"));
-++++ return 1;
-++++ }
-++++ }
-++++Index: src/filed/acl.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-++++retrieving revision 1.10.2.1
-++++diff -u -r1.10.2.1 acl.c
-++++--- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-+++++++ src/filed/acl.c 21 Nov 2005 13:17:59 -0000
-++++@@ -26,7 +26,7 @@
-++++ *
-++++ * Written by Preben 'Peppe' Guldberg, December MMIV
-++++ *
-++++- * Version $Id$
-+++++ * Version $Id$
-++++ */
-++++ /*
-++++ Copyright (C) 2004-2005 Kern Sibbald
-++++@@ -140,7 +140,7 @@
-++++
-++++ if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-++++ len = pm_strcpy(jcr->acl_text, acl_text);
-++++- free(acl_text);
-+++++ actuallyfree(acl_text);
-++++ return len;
-++++ }
-++++ return -1;
-++++@@ -270,7 +270,7 @@
-++++ if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
-++++ if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-++++ len = pm_strcpy(jcr->acl_text, acl_text);
-++++- free(acl_text);
-+++++ actuallyfree(acl_text);
-++++ return len;
-++++ }
-++++ }
-++++Index: src/findlib/bfile.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-++++retrieving revision 1.40
-++++diff -u -r1.40 bfile.c
-++++--- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-+++++++ src/findlib/bfile.c 21 Nov 2005 13:17:59 -0000
-++++@@ -623,13 +623,10 @@
-++++ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
-++++ {
-++++ POOLMEM *rsrc_fname;
-++++- size_t fname_len;
-++++
-++++- fname_len = strlen(fname);
-++++ rsrc_fname = get_pool_memory(PM_FNAME);
-++++- bstrncpy(rsrc_fname, fname, fname_len + 1);
-++++- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-++++- strlen(_PATH_RSRCFORKSPEC) + 1);
-+++++ pm_strcpy(rsrc_fname, fname);
-+++++ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
-++++ bopen(bfd, rsrc_fname, flags, mode);
-++++ free_pool_memory(rsrc_fname);
-++++ return bfd->fid;
-++++Index: src/lib/bnet_server.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-++++retrieving revision 1.39
-++++diff -u -r1.39 bnet_server.c
-++++--- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-+++++++ src/lib/bnet_server.c 21 Nov 2005 13:18:00 -0000
-++++@@ -153,7 +153,6 @@
-++++ /* Error, get out */
-++++ foreach_dlist(fd_ptr, &sockfds) {
-++++ close(fd_ptr->fd);
-++++- free((void *)fd_ptr);
-++++ }
-++++ Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
-++++ break;
-++++Index: src/stored/autochanger.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-++++retrieving revision 1.47.2.3
-++++diff -u -r1.47.2.3 autochanger.c
-++++--- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-+++++++ src/stored/autochanger.c 21 Nov 2005 13:18:00 -0000
-++++@@ -4,7 +4,7 @@
-++++ *
-++++ * Kern Sibbald, August MMII
-++++ *
-++++- * Version $Id$
-+++++ * Version $Id$
-++++ */
-++++ /*
-++++ Copyright (C) 2002-2005 Kern Sibbald
-++++@@ -163,6 +163,7 @@
-++++ rtn_stat = -1; /* hard error */
-++++ }
-++++ Dmsg2(400, "load slot %d status=%d\n", slot, status);
-+++++ unlock_changer(dcr);
-++++ } else {
-++++ status = 0; /* we got what we want */
-++++ dev->Slot = slot; /* set currently loaded slot */
-++++@@ -174,7 +175,6 @@
-++++ } else {
-++++ rtn_stat = 0; /* no changer found */
-++++ }
-++++- unlock_changer(dcr);
-++++ free_pool_memory(changer);
-++++ return rtn_stat;
-++++
-++++Index: src/stored/status.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/stored/status.c,v
-++++retrieving revision 1.44.2.1
-++++diff -u -r1.44.2.1 status.c
-++++--- src/stored/status.c 6 Oct 2005 07:04:13 -0000 1.44.2.1
-+++++++ src/stored/status.c 21 Nov 2005 13:18:00 -0000
-++++@@ -264,6 +264,7 @@
-++++ bool found = false;
-++++ int bps, sec;
-++++ JCR *jcr;
-+++++ DCR *dcr;
-++++ char JobName[MAX_NAME_LENGTH];
-++++ char b1[30], b2[30], b3[30];
-++++
-++++@@ -273,7 +274,8 @@
-++++ bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
-++++ job_type_to_str(jcr->JobType), jcr->Job);
-++++ }
-++++- if (jcr->dcr && jcr->dcr->device) {
-+++++ dcr = jcr->dcr;
-+++++ if (dcr && dcr->device) {
-++++ bstrncpy(JobName, jcr->Job, sizeof(JobName));
-++++ /* There are three periods after the Job name */
-++++ char *p;
-++++@@ -282,13 +284,16 @@
-++++ *p = 0;
-++++ }
-++++ }
-++++- bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\" device=\"%s\"\n"),
-+++++ bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\"\n"
-+++++ " pool=\"%s\" device=\"%s\"\n"),
-++++ job_level_to_str(jcr->JobLevel),
-++++ job_type_to_str(jcr->JobType),
-++++ JobName,
-++++ jcr->JobId,
-++++- jcr->dcr->VolumeName,
-++++- jcr->dcr->device->device_name);
-+++++ dcr->VolumeName,
-+++++ dcr->pool_name,
-+++++ dcr->dev?dcr->dev->print_name():
-+++++ dcr->device->device_name);
-++++ sec = time(NULL) - jcr->run_time;
-++++ if (sec <= 0) {
-++++ sec = 1;
-++++Index: src/stored/stored_conf.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/stored/stored_conf.c,v
-++++retrieving revision 1.76
-++++diff -u -r1.76 stored_conf.c
-++++--- src/stored/stored_conf.c 9 Sep 2005 09:40:04 -0000 1.76
-+++++++ src/stored/stored_conf.c 21 Nov 2005 13:18:00 -0000
-++++@@ -222,16 +222,16 @@
-++++ res->res_dev.hdr.name,
-++++ res->res_dev.media_type, res->res_dev.device_name,
-++++ res->res_dev.label_type);
-++++- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
-+++++ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d chgr_wait=%d\n",
-++++ res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-++++- res->res_dev.max_block_size);
-+++++ res->res_dev.max_block_size, res->res_dev.max_changer_wait);
-++++ sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-++++ res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-++++ res->res_dev.max_volume_size);
-++++ sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
-++++ res->res_dev.max_file_size, res->res_dev.volume_capacity);
-++++- sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-++++- sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-+++++ sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-+++++ sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-++++ res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
-++++ if (res->res_dev.changer_res) {
-++++ sendit(sock, " changer=%p\n", res->res_dev.changer_res);
-++++Index: src/tray-monitor/tray-monitor.c
-++++===================================================================
-++++RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-++++retrieving revision 1.25.2.1
-++++diff -u -r1.25.2.1 tray-monitor.c
-++++--- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-+++++++ src/tray-monitor/tray-monitor.c 21 Nov 2005 13:18:00 -0000
-++++@@ -4,7 +4,7 @@
-++++ *
-++++ * Nicolas Boichat, August MMIV
-++++ *
-++++- * Version $Id$
-+++++ * Version $Id$
-++++ */
-++++
-++++ /*
-++++@@ -881,7 +881,7 @@
-++++ }
-++++
-++++ if (item->D_sock == NULL) {
-++++- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-+++++ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
-++++ changeStatusMessage(item, _("Cannot connect to daemon."));
-++++ item->state = error;
-++++ item->oldstate = error;
-+++Index: patches/patches-1.38.0
-+++===================================================================
-+++RCS file: patches/patches-1.38.0
-+++diff -N patches/patches-1.38.0
-+++Index: patches/patches-1.38.1
-+++===================================================================
-+++RCS file: patches/patches-1.38.1
-+++diff -N patches/patches-1.38.1
-+++--- /dev/null 1 Jan 1970 00:00:00 -0000
-++++++ patches/patches-1.38.1 21 Nov 2005 18:19:05 -0000
-+++@@ -0,0 +1,14 @@
-++++20Nov05 1.38.1-to-1.38.2.patch
-++++ This patch fixes the following bugs:
-++++
-++++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++++ says this patch does not fix his problem)
-++++- Fix cancel failure bug. Bug #481
-++++- Fix failure when Pool name has spaces. Bug #487
-++++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++++- Fix a couple of free()s in src/filed/acl.c
-++++- Fix memory overrun in bfile.c in building OS X resource
-++++ fork filename. Bug #489
-++++
-++++
-+++Index: src/version.h
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/version.h,v
-+++retrieving revision 1.554.2.14
-+++diff -u -r1.554.2.14 version.h
-+++--- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-++++++ src/version.h 21 Nov 2005 18:19:06 -0000
-+++@@ -3,9 +3,9 @@
-+++ */
-+++
-+++ #undef VERSION
-+++-#define VERSION "1.38.1"
-+++-#define BDATE "14 November 2005"
-+++-#define LSMDATE "14Nov05"
-++++#define VERSION "1.38.2"
-++++#define BDATE "20 November 2005"
-++++#define LSMDATE "20Nov05"
-+++
-+++ /* Debug flags */
-+++ #undef DEBUG
-+++Index: src/dird/catreq.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-+++retrieving revision 1.77.2.1
-+++diff -u -r1.77.2.1 catreq.c
-+++--- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-++++++ src/dird/catreq.c 21 Nov 2005 18:19:06 -0000
-+++@@ -10,7 +10,7 @@
-+++ * Basic tasks done here:
-+++ * Handle Catalog services.
-+++ *
-+++- * Version $Id$
-++++ * Version $Id$
-+++ */
-+++ /*
-+++ Copyright (C) 2001-2005 Kern Sibbald
-+++@@ -117,6 +117,7 @@
-+++ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
-+++ memset(&pr, 0, sizeof(pr));
-+++ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-++++ unbash_spaces(pr.Name);
-+++ ok = db_get_pool_record(jcr, jcr->db, &pr);
-+++ if (ok) {
-+++ mr.PoolId = pr.PoolId;
-+++Index: src/dird/ua_restore.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-+++retrieving revision 1.101.2.1
-+++diff -u -r1.101.2.1 ua_restore.c
-+++--- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-++++++ src/dird/ua_restore.c 21 Nov 2005 18:19:06 -0000
-+++@@ -10,7 +10,7 @@
-+++ *
-+++ * Kern Sibbald, July MMII
-+++ *
-+++- * Version $Id$
-++++ * Version $Id$
-+++ */
-+++ /*
-+++ Copyright (C) 2002-2005 Kern Sibbald
-+++@@ -409,7 +409,7 @@
-+++ }
-+++ done = true;
-+++ switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
-+++- case -1: /* error */
-++++ case -1: /* error or cancel */
-+++ return 0;
-+++ case 0: /* list last 20 Jobs run */
-+++ gui_save = ua->jcr->gui;
-+++Index: src/dird/ua_run.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-+++retrieving revision 1.71
-+++diff -u -r1.71 ua_run.c
-+++--- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-++++++ src/dird/ua_run.c 21 Nov 2005 18:19:06 -0000
-+++@@ -851,6 +851,8 @@
-+++ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
-+++ }
-+++ goto try_again;
-++++ case -1: /* error or cancel */
-++++ goto bail_out;
-+++ default:
-+++ goto try_again;
-+++ }
-+++Index: src/dird/ua_select.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-+++retrieving revision 1.65.2.1
-+++diff -u -r1.65.2.1 ua_select.c
-+++--- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-++++++ src/dird/ua_select.c 21 Nov 2005 18:19:06 -0000
-+++@@ -4,7 +4,7 @@
-+++ *
-+++ * Kern Sibbald, October MMI
-+++ *
-+++- * Version $Id$
-++++ * Version $Id$
-+++ */
-+++ /*
-+++ Copyright (C) 2001-2005 Kern Sibbald
-+++@@ -149,7 +149,9 @@
-+++ }
-+++ }
-+++ UnlockRes();
-+++- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-++++ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-++++ return NULL;
-++++ }
-+++ store = (STORE *)GetResWithName(R_STORAGE, name);
-+++ return store;
-+++ }
-+++@@ -170,7 +172,9 @@
-+++ }
-+++ }
-+++ UnlockRes();
-+++- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-++++ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-++++ return NULL;
-++++ }
-+++ fs = (FILESET *)GetResWithName(R_FILESET, name);
-+++ return fs;
-+++ }
-+++@@ -202,7 +206,9 @@
-+++ }
-+++ }
-+++ UnlockRes();
-+++- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-++++ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-++++ return NULL;
-++++ }
-+++ catalog = (CAT *)GetResWithName(R_CATALOG, name);
-+++ }
-+++ return catalog;
-+++@@ -225,7 +231,9 @@
-+++ }
-+++ }
-+++ UnlockRes();
-+++- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-++++ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-++++ return NULL;
-++++ }
-+++ job = (JOB *)GetResWithName(R_JOB, name);
-+++ return job;
-+++ }
-+++@@ -246,7 +254,9 @@
-+++ }
-+++ }
-+++ UnlockRes();
-+++- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-++++ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-++++ return NULL;
-++++ }
-+++ job = (JOB *)GetResWithName(R_JOB, name);
-+++ return job;
-+++ }
-+++@@ -269,7 +279,9 @@
-+++ }
-+++ }
-+++ UnlockRes();
-+++- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-++++ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-++++ return NULL;
-++++ }
-+++ client = (CLIENT *)GetResWithName(R_CLIENT, name);
-+++ return client;
-+++ }
-+++@@ -551,7 +563,9 @@
-+++ }
-+++ }
-+++ UnlockRes();
-+++- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-++++ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-++++ return NULL;
-++++ }
-+++ pool = (POOL *)GetResWithName(R_POOL, name);
-+++ return pool;
-+++ }
-+++@@ -673,12 +687,16 @@
-+++ * Returns: -1 on error
-+++ * index base 0 on success, and choice
-+++ * is copied to prompt if not NULL
-++++ * prompt is set to the chosen prompt item string
-+++ */
-+++ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
-+++ {
-+++ int i, item;
-+++ char pmsg[MAXSTRING];
-+++
-++++ if (prompt) {
-++++ *prompt = 0;
-++++ }
-+++ if (ua->num_prompts == 2) {
-+++ item = 1;
-+++ if (prompt) {
-+++@@ -698,15 +716,11 @@
-+++ bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
-+++ }
-+++
-+++- if (prompt) {
-+++- *prompt = 0;
-+++- }
-+++-
-+++ for ( ;; ) {
-+++ /* First item is the prompt string, not the items */
-+++ if (ua->num_prompts == 1) {
-+++ bsendmsg(ua, _("Selection is empty!\n"));
-+++- item = 0; /* list is empty ! */
-++++ item = -1; /* list is empty ! */
-+++ break;
-+++ }
-+++ if (ua->num_prompts == 2) {
-+++@@ -741,7 +755,7 @@
-+++ free(ua->prompt[i]);
-+++ }
-+++ ua->num_prompts = 0;
-+++- return item - 1;
-++++ return item>0 ? item-1 : item;
-+++ }
-+++
-+++
-+++Index: src/dird/ua_update.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-+++retrieving revision 1.7
-+++diff -u -r1.7 ua_update.c
-+++--- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-++++++ src/dird/ua_update.c 21 Nov 2005 18:19:06 -0000
-+++@@ -590,7 +590,7 @@
-+++ update_all_vols_from_pool(ua);
-+++ return 1;
-+++ default: /* Done or error */
-+++- bsendmsg(ua, _("Selection done.\n"));
-++++ bsendmsg(ua, _("Selection terminated.\n"));
-+++ return 1;
-+++ }
-+++ }
-+++Index: src/filed/acl.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-+++retrieving revision 1.10.2.1
-+++diff -u -r1.10.2.1 acl.c
-+++--- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-++++++ src/filed/acl.c 21 Nov 2005 18:19:07 -0000
-+++@@ -26,7 +26,7 @@
-+++ *
-+++ * Written by Preben 'Peppe' Guldberg, December MMIV
-+++ *
-+++- * Version $Id$
-++++ * Version $Id$
-+++ */
-+++ /*
-+++ Copyright (C) 2004-2005 Kern Sibbald
-+++@@ -140,7 +140,7 @@
-+++
-+++ if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-+++ len = pm_strcpy(jcr->acl_text, acl_text);
-+++- free(acl_text);
-++++ actuallyfree(acl_text);
-+++ return len;
-+++ }
-+++ return -1;
-+++@@ -270,7 +270,7 @@
-+++ if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
-+++ if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-+++ len = pm_strcpy(jcr->acl_text, acl_text);
-+++- free(acl_text);
-++++ actuallyfree(acl_text);
-+++ return len;
-+++ }
-+++ }
-+++Index: src/findlib/bfile.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-+++retrieving revision 1.40
-+++diff -u -r1.40 bfile.c
-+++--- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-++++++ src/findlib/bfile.c 21 Nov 2005 18:19:07 -0000
-+++@@ -623,13 +623,10 @@
-+++ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
-+++ {
-+++ POOLMEM *rsrc_fname;
-+++- size_t fname_len;
-+++
-+++- fname_len = strlen(fname);
-+++ rsrc_fname = get_pool_memory(PM_FNAME);
-+++- bstrncpy(rsrc_fname, fname, fname_len + 1);
-+++- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-+++- strlen(_PATH_RSRCFORKSPEC) + 1);
-++++ pm_strcpy(rsrc_fname, fname);
-++++ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
-+++ bopen(bfd, rsrc_fname, flags, mode);
-+++ free_pool_memory(rsrc_fname);
-+++ return bfd->fid;
-+++Index: src/lib/bnet_server.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-+++retrieving revision 1.39
-+++diff -u -r1.39 bnet_server.c
-+++--- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-++++++ src/lib/bnet_server.c 21 Nov 2005 18:19:07 -0000
-+++@@ -153,7 +153,6 @@
-+++ /* Error, get out */
-+++ foreach_dlist(fd_ptr, &sockfds) {
-+++ close(fd_ptr->fd);
-+++- free((void *)fd_ptr);
-+++ }
-+++ Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
-+++ break;
-+++Index: src/stored/autochanger.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-+++retrieving revision 1.47.2.3
-+++diff -u -r1.47.2.3 autochanger.c
-+++--- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-++++++ src/stored/autochanger.c 21 Nov 2005 18:19:07 -0000
-+++@@ -4,7 +4,7 @@
-+++ *
-+++ * Kern Sibbald, August MMII
-+++ *
-+++- * Version $Id$
-++++ * Version $Id$
-+++ */
-+++ /*
-+++ Copyright (C) 2002-2005 Kern Sibbald
-+++@@ -163,6 +163,7 @@
-+++ rtn_stat = -1; /* hard error */
-+++ }
-+++ Dmsg2(400, "load slot %d status=%d\n", slot, status);
-++++ unlock_changer(dcr);
-+++ } else {
-+++ status = 0; /* we got what we want */
-+++ dev->Slot = slot; /* set currently loaded slot */
-+++@@ -174,7 +175,6 @@
-+++ } else {
-+++ rtn_stat = 0; /* no changer found */
-+++ }
-+++- unlock_changer(dcr);
-+++ free_pool_memory(changer);
-+++ return rtn_stat;
-+++
-+++Index: src/stored/status.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/stored/status.c,v
-+++retrieving revision 1.44.2.1
-+++diff -u -r1.44.2.1 status.c
-+++--- src/stored/status.c 6 Oct 2005 07:04:13 -0000 1.44.2.1
-++++++ src/stored/status.c 21 Nov 2005 18:19:08 -0000
-+++@@ -264,6 +264,7 @@
-+++ bool found = false;
-+++ int bps, sec;
-+++ JCR *jcr;
-++++ DCR *dcr;
-+++ char JobName[MAX_NAME_LENGTH];
-+++ char b1[30], b2[30], b3[30];
-+++
-+++@@ -273,7 +274,8 @@
-+++ bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
-+++ job_type_to_str(jcr->JobType), jcr->Job);
-+++ }
-+++- if (jcr->dcr && jcr->dcr->device) {
-++++ dcr = jcr->dcr;
-++++ if (dcr && dcr->device) {
-+++ bstrncpy(JobName, jcr->Job, sizeof(JobName));
-+++ /* There are three periods after the Job name */
-+++ char *p;
-+++@@ -282,13 +284,16 @@
-+++ *p = 0;
-+++ }
-+++ }
-+++- bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\" device=\"%s\"\n"),
-++++ bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\"\n"
-++++ " pool=\"%s\" device=\"%s\"\n"),
-+++ job_level_to_str(jcr->JobLevel),
-+++ job_type_to_str(jcr->JobType),
-+++ JobName,
-+++ jcr->JobId,
-+++- jcr->dcr->VolumeName,
-+++- jcr->dcr->device->device_name);
-++++ dcr->VolumeName,
-++++ dcr->pool_name,
-++++ dcr->dev?dcr->dev->print_name():
-++++ dcr->device->device_name);
-+++ sec = time(NULL) - jcr->run_time;
-+++ if (sec <= 0) {
-+++ sec = 1;
-+++Index: src/stored/stored_conf.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/stored/stored_conf.c,v
-+++retrieving revision 1.76
-+++diff -u -r1.76 stored_conf.c
-+++--- src/stored/stored_conf.c 9 Sep 2005 09:40:04 -0000 1.76
-++++++ src/stored/stored_conf.c 21 Nov 2005 18:19:08 -0000
-+++@@ -222,16 +222,16 @@
-+++ res->res_dev.hdr.name,
-+++ res->res_dev.media_type, res->res_dev.device_name,
-+++ res->res_dev.label_type);
-+++- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
-++++ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d chgr_wait=%d\n",
-+++ res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-+++- res->res_dev.max_block_size);
-++++ res->res_dev.max_block_size, res->res_dev.max_changer_wait);
-+++ sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-+++ res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-+++ res->res_dev.max_volume_size);
-+++ sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
-+++ res->res_dev.max_file_size, res->res_dev.volume_capacity);
-+++- sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-+++- sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-++++ sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-++++ sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-+++ res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
-+++ if (res->res_dev.changer_res) {
-+++ sendit(sock, " changer=%p\n", res->res_dev.changer_res);
-+++Index: src/tray-monitor/tray-monitor.c
-+++===================================================================
-+++RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-+++retrieving revision 1.25.2.1
-+++diff -u -r1.25.2.1 tray-monitor.c
-+++--- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-++++++ src/tray-monitor/tray-monitor.c 21 Nov 2005 18:19:08 -0000
-+++@@ -4,7 +4,7 @@
-+++ *
-+++ * Nicolas Boichat, August MMIV
-+++ *
-+++- * Version $Id$
-++++ * Version $Id$
-+++ */
-+++
-+++ /*
-+++@@ -881,7 +881,7 @@
-+++ }
-+++
-+++ if (item->D_sock == NULL) {
-+++- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-++++ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
-+++ changeStatusMessage(item, _("Cannot connect to daemon."));
-+++ item->state = error;
-+++ item->oldstate = error;
-++Index: patches/patches-1.38.0
-++===================================================================
-++RCS file: patches/patches-1.38.0
-++diff -N patches/patches-1.38.0
-++Index: patches/patches-1.38.1
-++===================================================================
-++RCS file: patches/patches-1.38.1
-++diff -N patches/patches-1.38.1
-++--- /dev/null 1 Jan 1970 00:00:00 -0000
-+++++ patches/patches-1.38.1 22 Nov 2005 10:42:22 -0000
-++@@ -0,0 +1,14 @@
-+++20Nov05 1.38.1-to-1.38.2.patch
-+++ This patch fixes the following bugs:
-+++
-+++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+++ says this patch does not fix his problem)
-+++- Fix cancel failure bug. Bug #481
-+++- Fix failure when Pool name has spaces. Bug #487
-+++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+++- Fix a couple of free()s in src/filed/acl.c
-+++- Fix memory overrun in bfile.c in building OS X resource
-+++ fork filename. Bug #489
-+++
-+++
-++Index: src/version.h
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/version.h,v
-++retrieving revision 1.554.2.14
-++diff -u -r1.554.2.14 version.h
-++--- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-+++++ src/version.h 22 Nov 2005 10:42:22 -0000
-++@@ -3,9 +3,9 @@
-++ */
-++
-++ #undef VERSION
-++-#define VERSION "1.38.1"
-++-#define BDATE "14 November 2005"
-++-#define LSMDATE "14Nov05"
-+++#define VERSION "1.38.2"
-+++#define BDATE "20 November 2005"
-+++#define LSMDATE "20Nov05"
-++
-++ /* Debug flags */
-++ #undef DEBUG
-++Index: src/dird/catreq.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-++retrieving revision 1.77.2.1
-++diff -u -r1.77.2.1 catreq.c
-++--- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-+++++ src/dird/catreq.c 22 Nov 2005 10:42:22 -0000
-++@@ -10,7 +10,7 @@
-++ * Basic tasks done here:
-++ * Handle Catalog services.
-++ *
-++- * Version $Id$
-+++ * Version $Id$
-++ */
-++ /*
-++ Copyright (C) 2001-2005 Kern Sibbald
-++@@ -117,6 +117,7 @@
-++ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
-++ memset(&pr, 0, sizeof(pr));
-++ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-+++ unbash_spaces(pr.Name);
-++ ok = db_get_pool_record(jcr, jcr->db, &pr);
-++ if (ok) {
-++ mr.PoolId = pr.PoolId;
-++Index: src/dird/ua_restore.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-++retrieving revision 1.101.2.1
-++diff -u -r1.101.2.1 ua_restore.c
-++--- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-+++++ src/dird/ua_restore.c 22 Nov 2005 10:42:23 -0000
-++@@ -10,7 +10,7 @@
-++ *
-++ * Kern Sibbald, July MMII
-++ *
-++- * Version $Id$
-+++ * Version $Id$
-++ */
-++ /*
-++ Copyright (C) 2002-2005 Kern Sibbald
-++@@ -409,7 +409,7 @@
-++ }
-++ done = true;
-++ switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
-++- case -1: /* error */
-+++ case -1: /* error or cancel */
-++ return 0;
-++ case 0: /* list last 20 Jobs run */
-++ gui_save = ua->jcr->gui;
-++Index: src/dird/ua_run.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-++retrieving revision 1.71
-++diff -u -r1.71 ua_run.c
-++--- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-+++++ src/dird/ua_run.c 22 Nov 2005 10:42:23 -0000
-++@@ -851,6 +851,8 @@
-++ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
-++ }
-++ goto try_again;
-+++ case -1: /* error or cancel */
-+++ goto bail_out;
-++ default:
-++ goto try_again;
-++ }
-++Index: src/dird/ua_select.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-++retrieving revision 1.65.2.1
-++diff -u -r1.65.2.1 ua_select.c
-++--- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-+++++ src/dird/ua_select.c 22 Nov 2005 10:42:23 -0000
-++@@ -4,7 +4,7 @@
-++ *
-++ * Kern Sibbald, October MMI
-++ *
-++- * Version $Id$
-+++ * Version $Id$
-++ */
-++ /*
-++ Copyright (C) 2001-2005 Kern Sibbald
-++@@ -149,7 +149,9 @@
-++ }
-++ }
-++ UnlockRes();
-++- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-+++ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-+++ return NULL;
-+++ }
-++ store = (STORE *)GetResWithName(R_STORAGE, name);
-++ return store;
-++ }
-++@@ -170,7 +172,9 @@
-++ }
-++ }
-++ UnlockRes();
-++- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-+++ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-+++ return NULL;
-+++ }
-++ fs = (FILESET *)GetResWithName(R_FILESET, name);
-++ return fs;
-++ }
-++@@ -202,7 +206,9 @@
-++ }
-++ }
-++ UnlockRes();
-++- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-+++ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-+++ return NULL;
-+++ }
-++ catalog = (CAT *)GetResWithName(R_CATALOG, name);
-++ }
-++ return catalog;
-++@@ -225,7 +231,9 @@
-++ }
-++ }
-++ UnlockRes();
-++- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-+++ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-+++ return NULL;
-+++ }
-++ job = (JOB *)GetResWithName(R_JOB, name);
-++ return job;
-++ }
-++@@ -246,7 +254,9 @@
-++ }
-++ }
-++ UnlockRes();
-++- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-+++ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-+++ return NULL;
-+++ }
-++ job = (JOB *)GetResWithName(R_JOB, name);
-++ return job;
-++ }
-++@@ -269,7 +279,9 @@
-++ }
-++ }
-++ UnlockRes();
-++- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-+++ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-+++ return NULL;
-+++ }
-++ client = (CLIENT *)GetResWithName(R_CLIENT, name);
-++ return client;
-++ }
-++@@ -551,7 +563,9 @@
-++ }
-++ }
-++ UnlockRes();
-++- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-+++ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-+++ return NULL;
-+++ }
-++ pool = (POOL *)GetResWithName(R_POOL, name);
-++ return pool;
-++ }
-++@@ -673,12 +687,16 @@
-++ * Returns: -1 on error
-++ * index base 0 on success, and choice
-++ * is copied to prompt if not NULL
-+++ * prompt is set to the chosen prompt item string
-++ */
-++ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
-++ {
-++ int i, item;
-++ char pmsg[MAXSTRING];
-++
-+++ if (prompt) {
-+++ *prompt = 0;
-+++ }
-++ if (ua->num_prompts == 2) {
-++ item = 1;
-++ if (prompt) {
-++@@ -698,15 +716,11 @@
-++ bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
-++ }
-++
-++- if (prompt) {
-++- *prompt = 0;
-++- }
-++-
-++ for ( ;; ) {
-++ /* First item is the prompt string, not the items */
-++ if (ua->num_prompts == 1) {
-++ bsendmsg(ua, _("Selection is empty!\n"));
-++- item = 0; /* list is empty ! */
-+++ item = -1; /* list is empty ! */
-++ break;
-++ }
-++ if (ua->num_prompts == 2) {
-++@@ -741,7 +755,7 @@
-++ free(ua->prompt[i]);
-++ }
-++ ua->num_prompts = 0;
-++- return item - 1;
-+++ return item>0 ? item-1 : item;
-++ }
-++
-++
-++Index: src/dird/ua_update.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-++retrieving revision 1.7
-++diff -u -r1.7 ua_update.c
-++--- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-+++++ src/dird/ua_update.c 22 Nov 2005 10:42:23 -0000
-++@@ -590,7 +590,7 @@
-++ update_all_vols_from_pool(ua);
-++ return 1;
-++ default: /* Done or error */
-++- bsendmsg(ua, _("Selection done.\n"));
-+++ bsendmsg(ua, _("Selection terminated.\n"));
-++ return 1;
-++ }
-++ }
-++Index: src/filed/acl.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-++retrieving revision 1.10.2.1
-++diff -u -r1.10.2.1 acl.c
-++--- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-+++++ src/filed/acl.c 22 Nov 2005 10:42:23 -0000
-++@@ -26,7 +26,7 @@
-++ *
-++ * Written by Preben 'Peppe' Guldberg, December MMIV
-++ *
-++- * Version $Id$
-+++ * Version $Id$
-++ */
-++ /*
-++ Copyright (C) 2004-2005 Kern Sibbald
-++@@ -140,7 +140,7 @@
-++
-++ if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-++ len = pm_strcpy(jcr->acl_text, acl_text);
-++- free(acl_text);
-+++ actuallyfree(acl_text);
-++ return len;
-++ }
-++ return -1;
-++@@ -270,7 +270,7 @@
-++ if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
-++ if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-++ len = pm_strcpy(jcr->acl_text, acl_text);
-++- free(acl_text);
-+++ actuallyfree(acl_text);
-++ return len;
-++ }
-++ }
-++Index: src/findlib/bfile.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-++retrieving revision 1.40
-++diff -u -r1.40 bfile.c
-++--- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-+++++ src/findlib/bfile.c 22 Nov 2005 10:42:24 -0000
-++@@ -623,13 +623,10 @@
-++ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
-++ {
-++ POOLMEM *rsrc_fname;
-++- size_t fname_len;
-++
-++- fname_len = strlen(fname);
-++ rsrc_fname = get_pool_memory(PM_FNAME);
-++- bstrncpy(rsrc_fname, fname, fname_len + 1);
-++- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-++- strlen(_PATH_RSRCFORKSPEC) + 1);
-+++ pm_strcpy(rsrc_fname, fname);
-+++ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
-++ bopen(bfd, rsrc_fname, flags, mode);
-++ free_pool_memory(rsrc_fname);
-++ return bfd->fid;
-++Index: src/lib/bnet_server.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-++retrieving revision 1.39
-++diff -u -r1.39 bnet_server.c
-++--- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-+++++ src/lib/bnet_server.c 22 Nov 2005 10:42:24 -0000
-++@@ -153,7 +153,6 @@
-++ /* Error, get out */
-++ foreach_dlist(fd_ptr, &sockfds) {
-++ close(fd_ptr->fd);
-++- free((void *)fd_ptr);
-++ }
-++ Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
-++ break;
-++Index: src/stored/autochanger.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-++retrieving revision 1.47.2.3
-++diff -u -r1.47.2.3 autochanger.c
-++--- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-+++++ src/stored/autochanger.c 22 Nov 2005 10:42:24 -0000
-++@@ -4,7 +4,7 @@
-++ *
-++ * Kern Sibbald, August MMII
-++ *
-++- * Version $Id$
-+++ * Version $Id$
-++ */
-++ /*
-++ Copyright (C) 2002-2005 Kern Sibbald
-++@@ -163,6 +163,7 @@
-++ rtn_stat = -1; /* hard error */
-++ }
-++ Dmsg2(400, "load slot %d status=%d\n", slot, status);
-+++ unlock_changer(dcr);
-++ } else {
-++ status = 0; /* we got what we want */
-++ dev->Slot = slot; /* set currently loaded slot */
-++@@ -174,7 +175,6 @@
-++ } else {
-++ rtn_stat = 0; /* no changer found */
-++ }
-++- unlock_changer(dcr);
-++ free_pool_memory(changer);
-++ return rtn_stat;
-++
-++Index: src/stored/status.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/stored/status.c,v
-++retrieving revision 1.44.2.1
-++diff -u -r1.44.2.1 status.c
-++--- src/stored/status.c 6 Oct 2005 07:04:13 -0000 1.44.2.1
-+++++ src/stored/status.c 22 Nov 2005 10:42:24 -0000
-++@@ -264,6 +264,7 @@
-++ bool found = false;
-++ int bps, sec;
-++ JCR *jcr;
-+++ DCR *dcr;
-++ char JobName[MAX_NAME_LENGTH];
-++ char b1[30], b2[30], b3[30];
-++
-++@@ -273,7 +274,8 @@
-++ bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
-++ job_type_to_str(jcr->JobType), jcr->Job);
-++ }
-++- if (jcr->dcr && jcr->dcr->device) {
-+++ dcr = jcr->dcr;
-+++ if (dcr && dcr->device) {
-++ bstrncpy(JobName, jcr->Job, sizeof(JobName));
-++ /* There are three periods after the Job name */
-++ char *p;
-++@@ -282,13 +284,16 @@
-++ *p = 0;
-++ }
-++ }
-++- bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\" device=\"%s\"\n"),
-+++ bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\"\n"
-+++ " pool=\"%s\" device=\"%s\"\n"),
-++ job_level_to_str(jcr->JobLevel),
-++ job_type_to_str(jcr->JobType),
-++ JobName,
-++ jcr->JobId,
-++- jcr->dcr->VolumeName,
-++- jcr->dcr->device->device_name);
-+++ dcr->VolumeName,
-+++ dcr->pool_name,
-+++ dcr->dev?dcr->dev->print_name():
-+++ dcr->device->device_name);
-++ sec = time(NULL) - jcr->run_time;
-++ if (sec <= 0) {
-++ sec = 1;
-++Index: src/stored/stored_conf.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/stored/stored_conf.c,v
-++retrieving revision 1.76
-++diff -u -r1.76 stored_conf.c
-++--- src/stored/stored_conf.c 9 Sep 2005 09:40:04 -0000 1.76
-+++++ src/stored/stored_conf.c 22 Nov 2005 10:42:24 -0000
-++@@ -222,16 +222,16 @@
-++ res->res_dev.hdr.name,
-++ res->res_dev.media_type, res->res_dev.device_name,
-++ res->res_dev.label_type);
-++- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
-+++ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d chgr_wait=%d\n",
-++ res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-++- res->res_dev.max_block_size);
-+++ res->res_dev.max_block_size, res->res_dev.max_changer_wait);
-++ sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-++ res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-++ res->res_dev.max_volume_size);
-++ sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
-++ res->res_dev.max_file_size, res->res_dev.volume_capacity);
-++- sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-++- sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-+++ sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-+++ sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-++ res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
-++ if (res->res_dev.changer_res) {
-++ sendit(sock, " changer=%p\n", res->res_dev.changer_res);
-++Index: src/tray-monitor/tray-monitor.c
-++===================================================================
-++RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-++retrieving revision 1.25.2.1
-++diff -u -r1.25.2.1 tray-monitor.c
-++--- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-+++++ src/tray-monitor/tray-monitor.c 22 Nov 2005 10:42:24 -0000
-++@@ -4,7 +4,7 @@
-++ *
-++ * Nicolas Boichat, August MMIV
-++ *
-++- * Version $Id$
-+++ * Version $Id$
-++ */
-++
-++ /*
-++@@ -881,7 +881,7 @@
-++ }
-++
-++ if (item->D_sock == NULL) {
-++- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-+++ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
-++ changeStatusMessage(item, _("Cannot connect to daemon."));
-++ item->state = error;
-++ item->oldstate = error;
-++Index: updatedb/kes-1.38
-++===================================================================
-++RCS file: updatedb/kes-1.38
-++diff -N updatedb/kes-1.38
-++--- updatedb/kes-1.38 3 Nov 2005 14:54:28 -0000 1.1.2.1
-+++++ /dev/null 1 Jan 1970 00:00:00 -0000
-++@@ -1,19 +0,0 @@
-++- Technical notes on version 1.38
-++- Kern Sibbald
-++-
-++-General:
-++-
-++-Changes to 1.38.0:
-++-- Modify configure.in to add execute option to sqlite3 catalog
-++- scripts.
-++-- Create update_xxx_table_8_to_9 scripts for updatedb
-++-- Fix wrong variable in bpipe.c debug output reported by user.
-++-- Fix improper placement of encode_and_send_attributes() in
-++- FD backup.c causing first file of non-portable Win32 backup
-++- to have wrong stream. Reported by Thorsten.
-++-- Move the -lcrypt for PostgreSQL after the PostgreSQL libs in
-++- autoconf/bacula-macros/db.m4 as suggested by user. Fixes bug #457.
-++-- Remove @STATIC_CONS@ from tray-monitor Makefile as suggested
-++- by user. Fixes bug #456.
-++-
-++-Released 1.38.0 (28Oct05): 31 October 2005
-+Index: patches/patches-1.38.0
-+===================================================================
-+RCS file: patches/patches-1.38.0
-+diff -N patches/patches-1.38.0
-+Index: patches/patches-1.38.1
-+===================================================================
-+RCS file: patches/patches-1.38.1
-+diff -N patches/patches-1.38.1
-+--- /dev/null 1 Jan 1970 00:00:00 -0000
-++++ patches/patches-1.38.1 22 Nov 2005 10:50:55 -0000 1.1.2.2
-+@@ -0,0 +1,14 @@
-++20Nov05 1.38.1-to-1.38.2.patch
-++ This patch fixes the following bugs:
-++
-++- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-++- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-++ says this patch does not fix his problem)
-++- Fix cancel failure bug. Bug #481
-++- Fix failure when Pool name has spaces. Bug #487
-++- Fix SD crash in autochanger code. Mutex failure. Bug #488
-++- Fix a couple of free()s in src/filed/acl.c
-++- Fix memory overrun in bfile.c in building OS X resource
-++ fork filename. Bug #489
-++
-++
-+Index: src/version.h
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/version.h,v
-+retrieving revision 1.554.2.14
-+retrieving revision 1.554.2.15
-+diff -u -r1.554.2.14 -r1.554.2.15
-+--- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-++++ src/version.h 22 Nov 2005 10:50:55 -0000 1.554.2.15
-+@@ -1,11 +1,11 @@
-+ /*
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+
-+ #undef VERSION
-+-#define VERSION "1.38.1"
-+-#define BDATE "14 November 2005"
-+-#define LSMDATE "14Nov05"
-++#define VERSION "1.38.2"
-++#define BDATE "20 November 2005"
-++#define LSMDATE "20Nov05"
-+
-+ /* Debug flags */
-+ #undef DEBUG
-+Index: src/dird/catreq.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-+retrieving revision 1.77.2.1
-+retrieving revision 1.77.2.2
-+diff -u -r1.77.2.1 -r1.77.2.2
-+--- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-++++ src/dird/catreq.c 22 Nov 2005 10:50:55 -0000 1.77.2.2
-+@@ -10,7 +10,7 @@
-+ * Basic tasks done here:
-+ * Handle Catalog services.
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2001-2005 Kern Sibbald
-+@@ -117,6 +117,7 @@
-+ if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
-+ memset(&pr, 0, sizeof(pr));
-+ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-++ unbash_spaces(pr.Name);
-+ ok = db_get_pool_record(jcr, jcr->db, &pr);
-+ if (ok) {
-+ mr.PoolId = pr.PoolId;
-+Index: src/dird/ua_restore.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-+retrieving revision 1.101.2.1
-+retrieving revision 1.101.2.2
-+diff -u -r1.101.2.1 -r1.101.2.2
-+--- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-++++ src/dird/ua_restore.c 22 Nov 2005 10:50:55 -0000 1.101.2.2
-+@@ -10,7 +10,7 @@
-+ *
-+ * Kern Sibbald, July MMII
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2002-2005 Kern Sibbald
-+@@ -409,7 +409,7 @@
-+ }
-+ done = true;
-+ switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
-+- case -1: /* error */
-++ case -1: /* error or cancel */
-+ return 0;
-+ case 0: /* list last 20 Jobs run */
-+ gui_save = ua->jcr->gui;
-+Index: src/dird/ua_run.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-+retrieving revision 1.71
-+retrieving revision 1.71.2.1
-+diff -u -r1.71 -r1.71.2.1
-+--- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-++++ src/dird/ua_run.c 22 Nov 2005 10:50:55 -0000 1.71.2.1
-+@@ -4,7 +4,7 @@
-+ *
-+ * Kern Sibbald, December MMI
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2001-2005 Kern Sibbald
-+@@ -851,6 +851,8 @@
-+ bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
-+ }
-+ goto try_again;
-++ case -1: /* error or cancel */
-++ goto bail_out;
-+ default:
-+ goto try_again;
-+ }
-+Index: src/dird/ua_select.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-+retrieving revision 1.65.2.1
-+retrieving revision 1.65.2.2
-+diff -u -r1.65.2.1 -r1.65.2.2
-+--- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-++++ src/dird/ua_select.c 22 Nov 2005 10:50:55 -0000 1.65.2.2
-+@@ -4,7 +4,7 @@
-+ *
-+ * Kern Sibbald, October MMI
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2001-2005 Kern Sibbald
-+@@ -149,7 +149,9 @@
-+ }
-+ }
-+ UnlockRes();
-+- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-++ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-++ return NULL;
-++ }
-+ store = (STORE *)GetResWithName(R_STORAGE, name);
-+ return store;
-+ }
-+@@ -170,7 +172,9 @@
-+ }
-+ }
-+ UnlockRes();
-+- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-++ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-++ return NULL;
-++ }
-+ fs = (FILESET *)GetResWithName(R_FILESET, name);
-+ return fs;
-+ }
-+@@ -202,7 +206,9 @@
-+ }
-+ }
-+ UnlockRes();
-+- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-++ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-++ return NULL;
-++ }
-+ catalog = (CAT *)GetResWithName(R_CATALOG, name);
-+ }
-+ return catalog;
-+@@ -225,7 +231,9 @@
-+ }
-+ }
-+ UnlockRes();
-+- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-++ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-++ return NULL;
-++ }
-+ job = (JOB *)GetResWithName(R_JOB, name);
-+ return job;
-+ }
-+@@ -246,7 +254,9 @@
-+ }
-+ }
-+ UnlockRes();
-+- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-++ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-++ return NULL;
-++ }
-+ job = (JOB *)GetResWithName(R_JOB, name);
-+ return job;
-+ }
-+@@ -269,7 +279,9 @@
-+ }
-+ }
-+ UnlockRes();
-+- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-++ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-++ return NULL;
-++ }
-+ client = (CLIENT *)GetResWithName(R_CLIENT, name);
-+ return client;
-+ }
-+@@ -551,7 +563,9 @@
-+ }
-+ }
-+ UnlockRes();
-+- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-++ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-++ return NULL;
-++ }
-+ pool = (POOL *)GetResWithName(R_POOL, name);
-+ return pool;
-+ }
-+@@ -673,12 +687,16 @@
-+ * Returns: -1 on error
-+ * index base 0 on success, and choice
-+ * is copied to prompt if not NULL
-++ * prompt is set to the chosen prompt item string
-+ */
-+ int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
-+ {
-+ int i, item;
-+ char pmsg[MAXSTRING];
-+
-++ if (prompt) {
-++ *prompt = 0;
-++ }
-+ if (ua->num_prompts == 2) {
-+ item = 1;
-+ if (prompt) {
-+@@ -698,15 +716,11 @@
-+ bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
-+ }
-+
-+- if (prompt) {
-+- *prompt = 0;
-+- }
-+-
-+ for ( ;; ) {
-+ /* First item is the prompt string, not the items */
-+ if (ua->num_prompts == 1) {
-+ bsendmsg(ua, _("Selection is empty!\n"));
-+- item = 0; /* list is empty ! */
-++ item = -1; /* list is empty ! */
-+ break;
-+ }
-+ if (ua->num_prompts == 2) {
-+@@ -741,7 +755,7 @@
-+ free(ua->prompt[i]);
-+ }
-+ ua->num_prompts = 0;
-+- return item - 1;
-++ return item>0 ? item-1 : item;
-+ }
-+
-+
-+Index: src/dird/ua_update.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-+retrieving revision 1.7
-+retrieving revision 1.7.2.1
-+diff -u -r1.7 -r1.7.2.1
-+--- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-++++ src/dird/ua_update.c 22 Nov 2005 10:50:55 -0000 1.7.2.1
-+@@ -5,7 +5,7 @@
-+ *
-+ * Kern Sibbald, September MM
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2000-2005 Kern Sibbald
-+@@ -590,7 +590,7 @@
-+ update_all_vols_from_pool(ua);
-+ return 1;
-+ default: /* Done or error */
-+- bsendmsg(ua, _("Selection done.\n"));
-++ bsendmsg(ua, _("Selection terminated.\n"));
-+ return 1;
-+ }
-+ }
-+Index: src/filed/acl.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-+retrieving revision 1.10.2.1
-+retrieving revision 1.10.2.2
-+diff -u -r1.10.2.1 -r1.10.2.2
-+--- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-++++ src/filed/acl.c 22 Nov 2005 10:50:55 -0000 1.10.2.2
-+@@ -26,7 +26,7 @@
-+ *
-+ * Written by Preben 'Peppe' Guldberg, December MMIV
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2004-2005 Kern Sibbald
-+@@ -140,7 +140,7 @@
-+
-+ if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
-+ len = pm_strcpy(jcr->acl_text, acl_text);
-+- free(acl_text);
-++ actuallyfree(acl_text);
-+ return len;
-+ }
-+ return -1;
-+@@ -270,7 +270,7 @@
-+ if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
-+ if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
-+ len = pm_strcpy(jcr->acl_text, acl_text);
-+- free(acl_text);
-++ actuallyfree(acl_text);
-+ return len;
-+ }
-+ }
-+Index: src/findlib/bfile.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-+retrieving revision 1.40
-+retrieving revision 1.40.2.1
-+diff -u -r1.40 -r1.40.2.1
-+--- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-++++ src/findlib/bfile.c 22 Nov 2005 10:50:55 -0000 1.40.2.1
-+@@ -5,7 +5,7 @@
-+ *
-+ * Kern Sibbald, April MMIII
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ *
-+ */
-+ /*
-+@@ -623,13 +623,10 @@
-+ int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
-+ {
-+ POOLMEM *rsrc_fname;
-+- size_t fname_len;
-+
-+- fname_len = strlen(fname);
-+ rsrc_fname = get_pool_memory(PM_FNAME);
-+- bstrncpy(rsrc_fname, fname, fname_len + 1);
-+- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-+- strlen(_PATH_RSRCFORKSPEC) + 1);
-++ pm_strcpy(rsrc_fname, fname);
-++ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
-+ bopen(bfd, rsrc_fname, flags, mode);
-+ free_pool_memory(rsrc_fname);
-+ return bfd->fid;
-+Index: src/lib/bnet_server.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-+retrieving revision 1.39
-+retrieving revision 1.39.2.1
-+diff -u -r1.39 -r1.39.2.1
-+--- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-++++ src/lib/bnet_server.c 22 Nov 2005 10:50:55 -0000 1.39.2.1
-+@@ -16,7 +16,7 @@
-+ * Originally written by Kern Sibbald for inclusion in apcupsd,
-+ * but heavily modified for Bacula
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+
-+ #include "bacula.h"
-+@@ -153,7 +153,6 @@
-+ /* Error, get out */
-+ foreach_dlist(fd_ptr, &sockfds) {
-+ close(fd_ptr->fd);
-+- free((void *)fd_ptr);
-+ }
-+ Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
-+ break;
-+Index: src/stored/autochanger.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-+retrieving revision 1.47.2.3
-+retrieving revision 1.47.2.4
-+diff -u -r1.47.2.3 -r1.47.2.4
-+--- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-++++ src/stored/autochanger.c 22 Nov 2005 10:50:55 -0000 1.47.2.4
-+@@ -4,7 +4,7 @@
-+ *
-+ * Kern Sibbald, August MMII
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2002-2005 Kern Sibbald
-+@@ -163,6 +163,7 @@
-+ rtn_stat = -1; /* hard error */
-+ }
-+ Dmsg2(400, "load slot %d status=%d\n", slot, status);
-++ unlock_changer(dcr);
-+ } else {
-+ status = 0; /* we got what we want */
-+ dev->Slot = slot; /* set currently loaded slot */
-+@@ -174,7 +175,6 @@
-+ } else {
-+ rtn_stat = 0; /* no changer found */
-+ }
-+- unlock_changer(dcr);
-+ free_pool_memory(changer);
-+ return rtn_stat;
-+
-+Index: src/stored/status.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/stored/status.c,v
-+retrieving revision 1.44.2.1
-+retrieving revision 1.44.2.2
-+diff -u -r1.44.2.1 -r1.44.2.2
-+--- src/stored/status.c 6 Oct 2005 07:04:13 -0000 1.44.2.1
-++++ src/stored/status.c 22 Nov 2005 10:50:55 -0000 1.44.2.2
-+@@ -3,7 +3,7 @@
-+ *
-+ * Kern Sibbald, May MMIII
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ *
-+ */
-+ /*
-+@@ -264,6 +264,7 @@
-+ bool found = false;
-+ int bps, sec;
-+ JCR *jcr;
-++ DCR *dcr;
-+ char JobName[MAX_NAME_LENGTH];
-+ char b1[30], b2[30], b3[30];
-+
-+@@ -273,7 +274,8 @@
-+ bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
-+ job_type_to_str(jcr->JobType), jcr->Job);
-+ }
-+- if (jcr->dcr && jcr->dcr->device) {
-++ dcr = jcr->dcr;
-++ if (dcr && dcr->device) {
-+ bstrncpy(JobName, jcr->Job, sizeof(JobName));
-+ /* There are three periods after the Job name */
-+ char *p;
-+@@ -282,13 +284,16 @@
-+ *p = 0;
-+ }
-+ }
-+- bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\" device=\"%s\"\n"),
-++ bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\"\n"
-++ " pool=\"%s\" device=\"%s\"\n"),
-+ job_level_to_str(jcr->JobLevel),
-+ job_type_to_str(jcr->JobType),
-+ JobName,
-+ jcr->JobId,
-+- jcr->dcr->VolumeName,
-+- jcr->dcr->device->device_name);
-++ dcr->VolumeName,
-++ dcr->pool_name,
-++ dcr->dev?dcr->dev->print_name():
-++ dcr->device->device_name);
-+ sec = time(NULL) - jcr->run_time;
-+ if (sec <= 0) {
-+ sec = 1;
-+Index: src/stored/stored_conf.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/stored/stored_conf.c,v
-+retrieving revision 1.76
-+retrieving revision 1.76.2.1
-+diff -u -r1.76 -r1.76.2.1
-+--- src/stored/stored_conf.c 9 Sep 2005 09:40:04 -0000 1.76
-++++ src/stored/stored_conf.c 22 Nov 2005 10:50:55 -0000 1.76.2.1
-+@@ -3,7 +3,7 @@
-+ *
-+ * Kern Sibbald, March MM
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+ /*
-+ Copyright (C) 2000-2005 Kern Sibbald
-+@@ -222,16 +222,16 @@
-+ res->res_dev.hdr.name,
-+ res->res_dev.media_type, res->res_dev.device_name,
-+ res->res_dev.label_type);
-+- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
-++ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d chgr_wait=%d\n",
-+ res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-+- res->res_dev.max_block_size);
-++ res->res_dev.max_block_size, res->res_dev.max_changer_wait);
-+ sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
-+ res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
-+ res->res_dev.max_volume_size);
-+ sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
-+ res->res_dev.max_file_size, res->res_dev.volume_capacity);
-+- sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-+- sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-++ sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-++ sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-+ res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
-+ if (res->res_dev.changer_res) {
-+ sendit(sock, " changer=%p\n", res->res_dev.changer_res);
-+Index: src/tray-monitor/tray-monitor.c
-+===================================================================
-+RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-+retrieving revision 1.25.2.1
-+retrieving revision 1.25.2.2
-+diff -u -r1.25.2.1 -r1.25.2.2
-+--- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-++++ src/tray-monitor/tray-monitor.c 22 Nov 2005 10:50:55 -0000 1.25.2.2
-+@@ -4,7 +4,7 @@
-+ *
-+ * Nicolas Boichat, August MMIV
-+ *
-+- * Version $Id$
-++ * Version $Id$
-+ */
-+
-+ /*
-+@@ -881,7 +881,7 @@
-+ }
-+
-+ if (item->D_sock == NULL) {
-+- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-++ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
-+ changeStatusMessage(item, _("Cannot connect to daemon."));
-+ item->state = error;
-+ item->oldstate = error;
-+Index: updatedb/kes-1.38
-+===================================================================
-+RCS file: updatedb/kes-1.38
-+diff -N updatedb/kes-1.38
-+--- updatedb/kes-1.38 3 Nov 2005 14:54:28 -0000 1.1.2.1
-++++ /dev/null 1 Jan 1970 00:00:00 -0000
-+@@ -1,19 +0,0 @@
-+- Technical notes on version 1.38
-+- Kern Sibbald
-+-
-+-General:
-+-
-+-Changes to 1.38.0:
-+-- Modify configure.in to add execute option to sqlite3 catalog
-+- scripts.
-+-- Create update_xxx_table_8_to_9 scripts for updatedb
-+-- Fix wrong variable in bpipe.c debug output reported by user.
-+-- Fix improper placement of encode_and_send_attributes() in
-+- FD backup.c causing first file of non-portable Win32 backup
-+- to have wrong stream. Reported by Thorsten.
-+-- Move the -lcrypt for PostgreSQL after the PostgreSQL libs in
-+- autoconf/bacula-macros/db.m4 as suggested by user. Fixes bug #457.
-+-- Remove @STATIC_CONS@ from tray-monitor Makefile as suggested
-+- by user. Fixes bug #456.
-+-
-+-Released 1.38.0 (28Oct05): 31 October 2005
-Index: patches/patches-1.38.0
-===================================================================
-RCS file: patches/patches-1.38.0
-diff -N patches/patches-1.38.0
-Index: patches/patches-1.38.1
-===================================================================
-RCS file: patches/patches-1.38.1
-diff -N patches/patches-1.38.1
---- /dev/null 1 Jan 1970 00:00:00 -0000
-+++ patches/patches-1.38.1 22 Nov 2005 10:50:55 -0000 1.1.2.2
-@@ -0,0 +1,14 @@
-+20Nov05 1.38.1-to-1.38.2.patch
-+ This patch fixes the following bugs:
-+
-+- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-+- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
-+ says this patch does not fix his problem)
-+- Fix cancel failure bug. Bug #481
-+- Fix failure when Pool name has spaces. Bug #487
-+- Fix SD crash in autochanger code. Mutex failure. Bug #488
-+- Fix a couple of free()s in src/filed/acl.c
-+- Fix memory overrun in bfile.c in building OS X resource
-+ fork filename. Bug #489
-+
-+
-Index: src/version.h
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/version.h,v
-retrieving revision 1.554.2.14
-retrieving revision 1.554.2.15
-diff -u -r1.554.2.14 -r1.554.2.15
---- src/version.h 14 Nov 2005 14:21:58 -0000 1.554.2.14
-+++ src/version.h 22 Nov 2005 10:50:55 -0000 1.554.2.15
-@@ -1,11 +1,11 @@
- /*
-- * Version $Id$
-+ * Version $Id$
- */
-
- #undef VERSION
--#define VERSION "1.38.1"
--#define BDATE "14 November 2005"
--#define LSMDATE "14Nov05"
-+#define VERSION "1.38.2"
-+#define BDATE "20 November 2005"
-+#define LSMDATE "20Nov05"
-
- /* Debug flags */
- #undef DEBUG
-Index: src/dird/catreq.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/catreq.c,v
-retrieving revision 1.77.2.1
-retrieving revision 1.77.2.2
-diff -u -r1.77.2.1 -r1.77.2.2
---- src/dird/catreq.c 26 Oct 2005 14:02:04 -0000 1.77.2.1
-+++ src/dird/catreq.c 22 Nov 2005 10:50:55 -0000 1.77.2.2
-@@ -10,7 +10,7 @@
- * Basic tasks done here:
- * Handle Catalog services.
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2001-2005 Kern Sibbald
-@@ -117,6 +117,7 @@
- if (sscanf(bs->msg, Find_media, &Job, &index, &pool_name, &mr.MediaType) == 4) {
- memset(&pr, 0, sizeof(pr));
- bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
-+ unbash_spaces(pr.Name);
- ok = db_get_pool_record(jcr, jcr->db, &pr);
- if (ok) {
- mr.PoolId = pr.PoolId;
-Index: src/dird/ua_restore.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_restore.c,v
-retrieving revision 1.101.2.1
-retrieving revision 1.101.2.2
-diff -u -r1.101.2.1 -r1.101.2.2
---- src/dird/ua_restore.c 26 Oct 2005 14:02:04 -0000 1.101.2.1
-+++ src/dird/ua_restore.c 22 Nov 2005 10:50:55 -0000 1.101.2.2
-@@ -10,7 +10,7 @@
- *
- * Kern Sibbald, July MMII
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2002-2005 Kern Sibbald
-@@ -409,7 +409,7 @@
- }
- done = true;
- switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
-- case -1: /* error */
-+ case -1: /* error or cancel */
- return 0;
- case 0: /* list last 20 Jobs run */
- gui_save = ua->jcr->gui;
-Index: src/dird/ua_run.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_run.c,v
-retrieving revision 1.71
-retrieving revision 1.71.2.1
-diff -u -r1.71 -r1.71.2.1
---- src/dird/ua_run.c 10 Aug 2005 16:35:19 -0000 1.71
-+++ src/dird/ua_run.c 22 Nov 2005 10:50:55 -0000 1.71.2.1
-@@ -4,7 +4,7 @@
- *
- * Kern Sibbald, December MMI
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2001-2005 Kern Sibbald
-@@ -851,6 +851,8 @@
- bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
- }
- goto try_again;
-+ case -1: /* error or cancel */
-+ goto bail_out;
- default:
- goto try_again;
- }
-Index: src/dird/ua_select.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_select.c,v
-retrieving revision 1.65.2.1
-retrieving revision 1.65.2.2
-diff -u -r1.65.2.1 -r1.65.2.2
---- src/dird/ua_select.c 12 Nov 2005 17:30:52 -0000 1.65.2.1
-+++ src/dird/ua_select.c 22 Nov 2005 10:50:55 -0000 1.65.2.2
-@@ -4,7 +4,7 @@
- *
- * Kern Sibbald, October MMI
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2001-2005 Kern Sibbald
-@@ -149,7 +149,9 @@
- }
- }
- UnlockRes();
-- do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name));
-+ if (do_prompt(ua, _("Storage"), _("Select Storage resource"), name, sizeof(name)) < 0) {
-+ return NULL;
-+ }
- store = (STORE *)GetResWithName(R_STORAGE, name);
- return store;
- }
-@@ -170,7 +172,9 @@
- }
- }
- UnlockRes();
-- do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
-+ if (do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name)) < 0) {
-+ return NULL;
-+ }
- fs = (FILESET *)GetResWithName(R_FILESET, name);
- return fs;
- }
-@@ -202,7 +206,9 @@
- }
- }
- UnlockRes();
-- do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name));
-+ if (do_prompt(ua, _("Catalog"), _("Select Catalog resource"), name, sizeof(name)) < 0) {
-+ return NULL;
-+ }
- catalog = (CAT *)GetResWithName(R_CATALOG, name);
- }
- return catalog;
-@@ -225,7 +231,9 @@
- }
- }
- UnlockRes();
-- do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
-+ if (do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name)) < 0) {
-+ return NULL;
-+ }
- job = (JOB *)GetResWithName(R_JOB, name);
- return job;
- }
-@@ -246,7 +254,9 @@
- }
- }
- UnlockRes();
-- do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name));
-+ if (do_prompt(ua, _("Job"), _("Select Restore Job"), name, sizeof(name)) < 0) {
-+ return NULL;
-+ }
- job = (JOB *)GetResWithName(R_JOB, name);
- return job;
- }
-@@ -269,7 +279,9 @@
- }
- }
- UnlockRes();
-- do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name));
-+ if (do_prompt(ua, _("Client"), _("Select Client (File daemon) resource"), name, sizeof(name)) < 0) {
-+ return NULL;
-+ }
- client = (CLIENT *)GetResWithName(R_CLIENT, name);
- return client;
- }
-@@ -551,7 +563,9 @@
- }
- }
- UnlockRes();
-- do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
-+ if (do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name)) < 0) {
-+ return NULL;
-+ }
- pool = (POOL *)GetResWithName(R_POOL, name);
- return pool;
- }
-@@ -673,12 +687,16 @@
- * Returns: -1 on error
- * index base 0 on success, and choice
- * is copied to prompt if not NULL
-+ * prompt is set to the chosen prompt item string
- */
- int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt)
- {
- int i, item;
- char pmsg[MAXSTRING];
-
-+ if (prompt) {
-+ *prompt = 0;
-+ }
- if (ua->num_prompts == 2) {
- item = 1;
- if (prompt) {
-@@ -698,15 +716,11 @@
- bsendmsg(ua, "%6d: %s\n", i, ua->prompt[i]);
- }
-
-- if (prompt) {
-- *prompt = 0;
-- }
--
- for ( ;; ) {
- /* First item is the prompt string, not the items */
- if (ua->num_prompts == 1) {
- bsendmsg(ua, _("Selection is empty!\n"));
-- item = 0; /* list is empty ! */
-+ item = -1; /* list is empty ! */
- break;
- }
- if (ua->num_prompts == 2) {
-@@ -741,7 +755,7 @@
- free(ua->prompt[i]);
- }
- ua->num_prompts = 0;
-- return item - 1;
-+ return item>0 ? item-1 : item;
- }
-
-
-Index: src/dird/ua_update.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/ua_update.c,v
-retrieving revision 1.7
-retrieving revision 1.7.2.1
-diff -u -r1.7 -r1.7.2.1
---- src/dird/ua_update.c 28 Aug 2005 12:22:02 -0000 1.7
-+++ src/dird/ua_update.c 22 Nov 2005 10:50:55 -0000 1.7.2.1
-@@ -5,7 +5,7 @@
- *
- * Kern Sibbald, September MM
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2000-2005 Kern Sibbald
-@@ -590,7 +590,7 @@
- update_all_vols_from_pool(ua);
- return 1;
- default: /* Done or error */
-- bsendmsg(ua, _("Selection done.\n"));
-+ bsendmsg(ua, _("Selection terminated.\n"));
- return 1;
- }
- }
-Index: src/filed/acl.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/filed/acl.c,v
-retrieving revision 1.10.2.1
-retrieving revision 1.10.2.2
-diff -u -r1.10.2.1 -r1.10.2.2
---- src/filed/acl.c 14 Nov 2005 20:20:38 -0000 1.10.2.1
-+++ src/filed/acl.c 22 Nov 2005 10:50:55 -0000 1.10.2.2
-@@ -26,7 +26,7 @@
- *
- * Written by Preben 'Peppe' Guldberg, December MMIV
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2004-2005 Kern Sibbald
-@@ -140,7 +140,7 @@
-
- if ((acl_text = acl_get(jcr->last_fname)) != NULL) {
- len = pm_strcpy(jcr->acl_text, acl_text);
-- free(acl_text);
-+ actuallyfree(acl_text);
- return len;
- }
- return -1;
-@@ -270,7 +270,7 @@
- if ((n = getacl(jcr->last_fname, n, acls)) > 0) {
- if ((acl_text = acltostr(n, acls, FORM_SHORT)) != NULL) {
- len = pm_strcpy(jcr->acl_text, acl_text);
-- free(acl_text);
-+ actuallyfree(acl_text);
- return len;
- }
- }
-Index: src/findlib/bfile.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/findlib/bfile.c,v
-retrieving revision 1.40
-retrieving revision 1.40.2.1
-diff -u -r1.40 -r1.40.2.1
---- src/findlib/bfile.c 10 Aug 2005 16:35:19 -0000 1.40
-+++ src/findlib/bfile.c 22 Nov 2005 10:50:55 -0000 1.40.2.1
-@@ -5,7 +5,7 @@
- *
- * Kern Sibbald, April MMIII
- *
-- * Version $Id$
-+ * Version $Id$
- *
- */
- /*
-@@ -623,13 +623,10 @@
- int bopen_rsrc(BFILE *bfd, const char *fname, int flags, mode_t mode)
- {
- POOLMEM *rsrc_fname;
-- size_t fname_len;
-
-- fname_len = strlen(fname);
- rsrc_fname = get_pool_memory(PM_FNAME);
-- bstrncpy(rsrc_fname, fname, fname_len + 1);
-- bstrncpy(rsrc_fname + fname_len, _PATH_RSRCFORKSPEC,
-- strlen(_PATH_RSRCFORKSPEC) + 1);
-+ pm_strcpy(rsrc_fname, fname);
-+ pm_strcat(rsrc_fname, _PATH_RSRCFORKSPEC);
- bopen(bfd, rsrc_fname, flags, mode);
- free_pool_memory(rsrc_fname);
- return bfd->fid;
-Index: src/lib/bnet_server.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/lib/bnet_server.c,v
-retrieving revision 1.39
-retrieving revision 1.39.2.1
-diff -u -r1.39 -r1.39.2.1
---- src/lib/bnet_server.c 18 Aug 2005 15:37:40 -0000 1.39
-+++ src/lib/bnet_server.c 22 Nov 2005 10:50:55 -0000 1.39.2.1
-@@ -16,7 +16,7 @@
- * Originally written by Kern Sibbald for inclusion in apcupsd,
- * but heavily modified for Bacula
- *
-- * Version $Id$
-+ * Version $Id$
- */
-
- #include "bacula.h"
-@@ -153,7 +153,6 @@
- /* Error, get out */
- foreach_dlist(fd_ptr, &sockfds) {
- close(fd_ptr->fd);
-- free((void *)fd_ptr);
- }
- Emsg1(M_FATAL, 0, _("Error in select: %s\n"), be.strerror());
- break;
-Index: src/stored/autochanger.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/autochanger.c,v
-retrieving revision 1.47.2.3
-retrieving revision 1.47.2.4
-diff -u -r1.47.2.3 -r1.47.2.4
---- src/stored/autochanger.c 12 Nov 2005 17:30:53 -0000 1.47.2.3
-+++ src/stored/autochanger.c 22 Nov 2005 10:50:55 -0000 1.47.2.4
-@@ -4,7 +4,7 @@
- *
- * Kern Sibbald, August MMII
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2002-2005 Kern Sibbald
-@@ -163,6 +163,7 @@
- rtn_stat = -1; /* hard error */
- }
- Dmsg2(400, "load slot %d status=%d\n", slot, status);
-+ unlock_changer(dcr);
- } else {
- status = 0; /* we got what we want */
- dev->Slot = slot; /* set currently loaded slot */
-@@ -174,7 +175,6 @@
- } else {
- rtn_stat = 0; /* no changer found */
- }
-- unlock_changer(dcr);
- free_pool_memory(changer);
- return rtn_stat;
-
-Index: src/stored/status.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/status.c,v
-retrieving revision 1.44.2.1
-retrieving revision 1.44.2.2
-diff -u -r1.44.2.1 -r1.44.2.2
---- src/stored/status.c 6 Oct 2005 07:04:13 -0000 1.44.2.1
-+++ src/stored/status.c 22 Nov 2005 10:50:55 -0000 1.44.2.2
-@@ -3,7 +3,7 @@
- *
- * Kern Sibbald, May MMIII
- *
-- * Version $Id$
-+ * Version $Id$
- *
- */
- /*
-@@ -264,6 +264,7 @@
- bool found = false;
- int bps, sec;
- JCR *jcr;
-+ DCR *dcr;
- char JobName[MAX_NAME_LENGTH];
- char b1[30], b2[30], b3[30];
-
-@@ -273,7 +274,8 @@
- bnet_fsend(user, _("%s Job %s waiting for Client connection.\n"),
- job_type_to_str(jcr->JobType), jcr->Job);
- }
-- if (jcr->dcr && jcr->dcr->device) {
-+ dcr = jcr->dcr;
-+ if (dcr && dcr->device) {
- bstrncpy(JobName, jcr->Job, sizeof(JobName));
- /* There are three periods after the Job name */
- char *p;
-@@ -282,13 +284,16 @@
- *p = 0;
- }
- }
-- bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\" device=\"%s\"\n"),
-+ bnet_fsend(user, _("%s %s job %s JobId=%d Volume=\"%s\"\n"
-+ " pool=\"%s\" device=\"%s\"\n"),
- job_level_to_str(jcr->JobLevel),
- job_type_to_str(jcr->JobType),
- JobName,
- jcr->JobId,
-- jcr->dcr->VolumeName,
-- jcr->dcr->device->device_name);
-+ dcr->VolumeName,
-+ dcr->pool_name,
-+ dcr->dev?dcr->dev->print_name():
-+ dcr->device->device_name);
- sec = time(NULL) - jcr->run_time;
- if (sec <= 0) {
- sec = 1;
-Index: src/stored/stored_conf.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/stored_conf.c,v
-retrieving revision 1.76
-retrieving revision 1.76.2.1
-diff -u -r1.76 -r1.76.2.1
---- src/stored/stored_conf.c 9 Sep 2005 09:40:04 -0000 1.76
-+++ src/stored/stored_conf.c 22 Nov 2005 10:50:55 -0000 1.76.2.1
-@@ -3,7 +3,7 @@
- *
- * Kern Sibbald, March MM
- *
-- * Version $Id$
-+ * Version $Id$
- */
- /*
- Copyright (C) 2000-2005 Kern Sibbald
-@@ -222,16 +222,16 @@
- res->res_dev.hdr.name,
- res->res_dev.media_type, res->res_dev.device_name,
- res->res_dev.label_type);
-- sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d\n",
-+ sendit(sock, " rew_wait=%d min_bs=%d max_bs=%d chgr_wait=%d\n",
- res->res_dev.max_rewind_wait, res->res_dev.min_block_size,
-- res->res_dev.max_block_size);
-+ res->res_dev.max_block_size, res->res_dev.max_changer_wait);
- sendit(sock, " max_jobs=%d max_files=%" lld " max_size=%" lld "\n",
- res->res_dev.max_volume_jobs, res->res_dev.max_volume_files,
- res->res_dev.max_volume_size);
- sendit(sock, " max_file_size=%" lld " capacity=%" lld "\n",
- res->res_dev.max_file_size, res->res_dev.volume_capacity);
-- sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-- sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
-+ sendit(sock, " spool_directory=%s\n", NPRT(res->res_dev.spool_directory));
-+ sendit(sock, " max_spool_size=%" lld " max_job_spool_size=%" lld "\n",
- res->res_dev.max_spool_size, res->res_dev.max_job_spool_size);
- if (res->res_dev.changer_res) {
- sendit(sock, " changer=%p\n", res->res_dev.changer_res);
-Index: src/tray-monitor/tray-monitor.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/tray-monitor/tray-monitor.c,v
-retrieving revision 1.25.2.1
-retrieving revision 1.25.2.2
-diff -u -r1.25.2.1 -r1.25.2.2
---- src/tray-monitor/tray-monitor.c 1 Oct 2005 10:20:18 -0000 1.25.2.1
-+++ src/tray-monitor/tray-monitor.c 22 Nov 2005 10:50:55 -0000 1.25.2.2
-@@ -4,7 +4,7 @@
- *
- * Nicolas Boichat, August MMIV
- *
-- * Version $Id$
-+ * Version $Id$
- */
-
- /*
-@@ -881,7 +881,7 @@
- }
-
- if (item->D_sock == NULL) {
-- g_slist_append(*list, (void *)_("Cannot connect to daemon.\n"));
-+ g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
- changeStatusMessage(item, _("Cannot connect to daemon."));
- item->state = error;
- item->oldstate = error;
-Index: updatedb/kes-1.38
-===================================================================
-RCS file: updatedb/kes-1.38
-diff -N updatedb/kes-1.38
---- updatedb/kes-1.38 3 Nov 2005 14:54:28 -0000 1.1.2.1
-+++ /dev/null 1 Jan 1970 00:00:00 -0000
-@@ -1,19 +0,0 @@
-- Technical notes on version 1.38
-- Kern Sibbald
--
--General:
--
--Changes to 1.38.0:
--- Modify configure.in to add execute option to sqlite3 catalog
-- scripts.
--- Create update_xxx_table_8_to_9 scripts for updatedb
--- Fix wrong variable in bpipe.c debug output reported by user.
--- Fix improper placement of encode_and_send_attributes() in
-- FD backup.c causing first file of non-portable Win32 backup
-- to have wrong stream. Reported by Thorsten.
--- Move the -lcrypt for PostgreSQL after the PostgreSQL libs in
-- autoconf/bacula-macros/db.m4 as suggested by user. Fixes bug #457.
--- Remove @STATIC_CONS@ from tray-monitor Makefile as suggested
-- by user. Fixes bug #456.
--
--Released 1.38.0 (28Oct05): 31 October 2005
+++ /dev/null
-Index: src/stored/block.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/stored/block.c,v
-retrieving revision 1.116.2.3
-diff -u -u -b -r1.116.2.3 block.c
---- src/stored/block.c 24 Mar 2006 16:35:23 -0000 1.116.2.3
-+++ src/stored/block.c 12 Jun 2006 16:19:27 -0000
-@@ -9,7 +9,7 @@
- *
- */
- /*
-- Copyright (C) 2001-2005 Kern Sibbald
-+ Copyright (C) 2001-2006 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
-@@ -910,13 +910,12 @@
- Dmsg3(100, "Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0),
- ((dev->file_addr-dev->part_start) == dev->part_size),
- (dev->part <= dev->VolCatInfo.VolCatParts));*/
-- /* Check for part file end */
-- if ((dev->num_parts > 0) &&
-- ((dev->file_addr-dev->part_start) == dev->part_size) &&
-- (dev->part < dev->num_parts)) {
-+ /* Check for DVD part file end */
-+ if (dev->at_eof() && dev->is_dvd() && dev->num_parts > 0 &&
-+ dev->part < dev->num_parts) {
- if (dvd_open_next_part(dcr) < 0) {
-- Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
-- dev->print_name(), strerror_dev(dev));
-+ Jmsg3(dcr->jcr, M_FATAL, 0, _("Unable to open device part=%d %s: ERR=%s\n"),
-+ dev->part, dev->print_name(), strerror_dev(dev));
- dev->dev_errno = EIO;
- return false;
- }
+++ /dev/null
-
- This patch should correct the FreeBSD mutex crash that happens in
- the Director after a sudden clock shift or after the "reload" command.
- Apply it to 1.38.10 (will not work with prior version) with:
-
- cd <bacula-source>
- patch -p0 <1.38.10-scheduler.patch
- make
- make install
- ...
-
-
-
-Index: src/dird/scheduler.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/scheduler.c,v
-retrieving revision 1.33.2.2
-diff -u -r1.33.2.2 scheduler.c
---- src/dird/scheduler.c 4 Jun 2006 12:24:39 -0000 1.33.2.2
-+++ src/dird/scheduler.c 24 Jun 2006 17:25:58 -0000
-@@ -151,6 +151,7 @@
- free(next_job);
- }
- schedules_invalidated = false;
-+ unlock_jobs();
- goto again;
- }
- unlock_jobs();
+++ /dev/null
-
- This patch fixes a bug in the bacula start/stop script where
- the binary directory is used rather than the scripts directory.
- Apply the patch to version 1.38.6 with:
-
- cd <bacula-source>
- patch -p0 <1.38.6-script.patch
- make Makefiles
- make install
- ...
-
-Index: scripts/bacula.in
-===================================================================
-RCS file: /cvsroot/bacula/bacula/scripts/bacula.in,v
-retrieving revision 1.13.2.3
-diff -u -r1.13.2.3 bacula.in
---- scripts/bacula.in 28 Mar 2006 16:42:19 -0000 1.13.2.3
-+++ scripts/bacula.in 29 Mar 2006 16:24:51 -0000
-@@ -13,25 +13,22 @@
- # easier to "steal" this code for the development
- # environment where they are different.
- #
--BACFDBIN=@sbindir@
- BACFDCFG=@sysconfdir@
--BACSDBIN=@sbindir@
- BACSDCFG=@sysconfdir@
--BACDIRBIN=@sbindir@
- BACDIRCFG=@sysconfdir@
-
- case "$1" in
- start)
-- [ -x ${BACSDBIN}/bacula-ctl-sd ] && ${BACSDBIN}/bacula-ctl-sd $1 $2
-- [ -x ${BACFDBIN}/bacula-ctl-fd ] && ${BACFDBIN}/bacula-ctl-fd $1 $2
-- [ -x ${BACDIRBIN}/bacula-ctl-dir ] && ${BACDIRBIN}/bacula-ctl-dir $1 $2
-+ [ -x ${BACSDCFG}/bacula-ctl-sd ] && ${BACSDCFG}/bacula-ctl-sd $1 $2
-+ [ -x ${BACFDCFG}/bacula-ctl-fd ] && ${BACFDCFG}/bacula-ctl-fd $1 $2
-+ [ -x ${BACDIRCFG}/bacula-ctl-dir ] && ${BACDIRCFG}/bacula-ctl-dir $1 $2
- ;;
-
- stop)
- # Stop the FD first so that SD will fail jobs and update catalog
-- [ -x ${BACFDBIN}/bacula-ctl-fd ] && ${BACFDBIN}/bacula-ctl-fd $1 $2
-- [ -x ${BACSDBIN}/bacula-ctl-sd ] && ${BACSDBIN}/bacula-ctl-sd $1 $2
-- [ -x ${BACDIRBIN}/bacula-ctl-dir ] && ${BACDIRBIN}/bacula-ctl-dir $1 $2
-+ [ -x ${BACFDCFG}/bacula-ctl-fd ] && ${BACFDCFG}/bacula-ctl-fd $1 $2
-+ [ -x ${BACSDCFG}/bacula-ctl-sd ] && ${BACSDCFG}/bacula-ctl-sd $1 $2
-+ [ -x ${BACDIRCFG}/bacula-ctl-dir ] && ${BACDIRCFG}/bacula-ctl-dir $1 $2
- echo
- sleep 6
- ;;
-@@ -42,9 +39,9 @@
- ;;
-
- status)
-- [ -x ${BACSDBIN}/bacula-ctl-sd ] && ${BACSDBIN}/bacula-ctl-sd status
-- [ -x ${BACFDBIN}/bacula-ctl-fd ] && ${BACFDBIN}/bacula-ctl-fd status
-- [ -x ${BACDIRBIN}/bacula-ctl-dir ] && ${BACDIRBIN}/bacula-ctl-dir status
-+ [ -x ${BACSDCFG}/bacula-ctl-sd ] && ${BACSDCFG}/bacula-ctl-sd status
-+ [ -x ${BACFDCFG}/bacula-ctl-fd ] && ${BACFDCFG}/bacula-ctl-fd status
-+ [ -x ${BACDIRCFG}/bacula-ctl-dir ] && ${BACDIRCFG}/bacula-ctl-dir status
- ;;
-
- *)
+++ /dev/null
-
-This patch (thanks to Frank Sweetser) should fix the timeout problem
-users are experiencing with MySQL versions greater than 5.0.13.
-It can be applied to Bacula version 1.38.7 (and possibly 1.38.5 and 1.38.6)
-with:
-
- cd <bacula-source>
- patch -p0 <1.38.7-mysql.patch
- make
- make install
-
-Index: src/cats/mysql.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/cats/mysql.c,v
-retrieving revision 1.37.2.2
-diff -u -r1.37.2.2 mysql.c
---- src/cats/mysql.c 4 Mar 2006 11:10:17 -0000 1.37.2.2
-+++ src/cats/mysql.c 7 Apr 2006 14:10:23 -0000
-@@ -132,7 +132,6 @@
- mysql_server_init(0, NULL, NULL);
- #endif
- mysql_init(&(mdb->mysql));
-- mdb->mysql.reconnect = 1; /* so connection does not timeout */
- Dmsg0(50, "mysql_init done\n");
- /* If connection fails, try at 5 sec intervals for 30 seconds. */
- for (int retry=0; retry < 6; retry++) {
-@@ -153,6 +152,7 @@
- bmicrosleep(5,0);
- }
-
-+ mdb->mysql.reconnect = 1; /* so connection does not timeout */
- Dmsg0(50, "mysql_real_connect done\n");
- Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", mdb->db_user, mdb->db_name,
- mdb->db_password==NULL?"(NULL)":mdb->db_password);
+++ /dev/null
-20Nov05 1.38.1-to-1.38.2.patch
- This patch fixes the following bugs:
-
-- Fix crash in tray-monitor when daemon disconnects. Bug #479.
-- Fix bnet-server bug found on OpenBSD. Bug #486 (bug originator
- says this patch does not fix his problem)
-- Fix cancel failure bug. Bug #481
-- Fix failure when Pool name has spaces. Bug #487
-- Fix SD crash in autochanger code. Mutex failure. Bug #488
-- Fix a couple of free()s in src/filed/acl.c
-- Fix memory overrun in bfile.c in building OS X resource
- fork filename. Bug #489
-
-
+++ /dev/null
-
- This patch should fix the Job restart on error bug that promotes
- an Incremental backup to a Full backup.
-
- Apply it to version 2.0.1 (perhaps to 2.0.0) with:
-
- cd <bacula-source>
- patch -p0 <2.0.1-restart.patch
- make
- ...
- make install
-
-Index: src/dird/job.c
-===================================================================
-RCS file: /cvsroot/bacula/bacula/src/dird/job.c,v
-retrieving revision 1.148.2.2
-diff -u -r1.148.2.2 job.c
---- src/dird/job.c 12 Jan 2007 09:58:04 -0000 1.148.2.2
-+++ src/dird/job.c 17 Jan 2007 15:29:25 -0000
-@@ -852,11 +852,6 @@
- free_pool_memory(jcr->fname);
- jcr->fname = NULL;
- }
-- if (jcr->stime) {
-- Dmsg0(200, "Free JCR stime\n");
-- free_pool_memory(jcr->stime);
-- jcr->stime = NULL;
-- }
- if (jcr->RestoreBootstrap) {
- free(jcr->RestoreBootstrap);
- jcr->RestoreBootstrap = NULL;
-@@ -889,6 +884,11 @@
- pthread_cond_destroy(&jcr->term_wait);
- jcr->term_wait_inited = false;
- }
-+ if (jcr->stime) {
-+ Dmsg0(200, "Free JCR stime\n");
-+ free_pool_memory(jcr->stime);
-+ jcr->stime = NULL;
-+ }
- if (jcr->fname) {
- Dmsg0(200, "Free JCR fname\n");
- free_pool_memory(jcr->fname);
+++ /dev/null
-This patch should resolve some problems with handling of am/pm
-in schedules as reported by bug #808.
-
-According to the NIST (US National Institute of Standards and Technology),
-12am and 12pm are ambiguous and can be defined to anything. However,
-12:01am is the same as 00:01 and 12:01pm is the same as 12:01, so Bacula
-defines 12am as 00:00 (midnight) and 12pm as 12:00 (noon). You can avoid
-this abiguity (confusion) by using 24 hour time specifications (i.e. no
-am/pm). This is the definition in Bacula version 2.0.3 and later.
-
-Apply it to version 2.0.3 with:
-
- cd <bacula-source>
- patch -p0 <2.0.3-ampm.patch
- make
- ...
- make install
-
-Index: src/dird/run_conf.c
-===================================================================
---- src/dird/run_conf.c (revision 4349)
-+++ src/dird/run_conf.c (working copy)
-@@ -339,6 +339,7 @@
- for ( ; token != T_EOL; (token = lex_get_token(lc, T_ALL))) {
- int len;
- bool pm = false;
-+ bool am = false;
- switch (token) {
- case T_NUMBER:
- state = s_mday;
-@@ -434,6 +435,7 @@
- if (!have_hour) {
- clear_bits(0, 23, lrun.hour);
- }
-+// Dmsg1(000, "s_time=%s\n", lc->str);
- p = strchr(lc->str, ':');
- if (!p) {
- scan_err0(lc, _("Time logic error.\n"));
-@@ -441,20 +443,19 @@
- }
- *p++ = 0; /* separate two halves */
- code = atoi(lc->str); /* pick up hour */
-+ code2 = atoi(p); /* pick up minutes */
- len = strlen(p);
-- if (len > 2 && p[len-1] == 'm') {
-- if (p[len-2] == 'a') {
-- pm = false;
-- } else if (p[len-2] == 'p') {
-- pm = true;
-- } else {
-- scan_err0(lc, _("Bad time specification."));
-- /* NOT REACHED */
-- }
-- } else {
-- pm = false;
-+ if (len >= 2) {
-+ p += 2;
- }
-- code2 = atoi(p); /* pick up minutes */
-+ if (strcasecmp(p, "pm") == 0) {
-+ pm = true;
-+ } else if (strcasecmp(p, "am") == 0) {
-+ am = true;
-+ } else if (len != 2) {
-+ scan_err0(lc, _("Bad time specification."));
-+ /* NOT REACHED */
-+ }
- /*
- * Note, according to NIST, 12am and 12pm are ambiguous and
- * can be defined to anything. However, 12:01am is the same
-@@ -467,13 +468,14 @@
- code += 12;
- }
- /* am */
-- } else if (code == 12) {
-+ } else if (am && code == 12) {
- code -= 12;
- }
- if (code < 0 || code > 23 || code2 < 0 || code2 > 59) {
- scan_err0(lc, _("Bad time specification."));
- /* NOT REACHED */
- }
-+// Dmsg2(000, "hour=%d min=%d\n", code, code2);
- set_bit(code, lrun.hour);
- lrun.minute = code2;
- have_hour = true;
+++ /dev/null
-
- This patch adds the MaxVolBytes to the output of a "show pools" command.
- It fixes bug #814. Apply it to Bacula version 2.0.3 with:
-
- cd <bacula-source>
- patch -p0 <2.0.3-maxbyteslist.patch
- make
- ...
- make install
-
-
-Index: src/dird/dird_conf.c
-===================================================================
---- src/dird/dird_conf.c (revision 4349)
-+++ src/dird/dird_conf.c (working copy)
-@@ -844,10 +844,13 @@
- NPRT(res->res_pool.label_format));
- sendit(sock, _(" CleaningPrefix=%s LabelType=%d\n"),
- NPRT(res->res_pool.cleaning_prefix), res->res_pool.LabelType);
-- sendit(sock, _(" RecyleOldest=%d PurgeOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n"),
-+ sendit(sock, _(" RecyleOldest=%d PurgeOldest=%d\n"),
- res->res_pool.recycle_oldest_volume,
-- res->res_pool.purge_oldest_volume,
-- res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles);
-+ res->res_pool.purge_oldest_volume);
-+ sendit(sock, _(" MaxVolJobs=%d MaxVolFiles=%d MaxVolBytes=%s\n"),
-+ res->res_pool.MaxVolJobs,
-+ res->res_pool.MaxVolFiles,
-+ edit_uint64(res->res_pool.MaxVolFiles, ed1));
- sendit(sock, _(" MigTime=%s MigHiBytes=%s MigLoBytes=%s\n"),
- edit_utime(res->res_pool.MigrationTime, ed1, sizeof(ed1)),
- edit_uint64(res->res_pool.MigrationHighBytes, ed2),
+++ /dev/null
-
-This patch should fix the logic error in checking for the MaxWaitTime of
-a job in src/dird/job.c. It fixes bug #802.
-
-Apply it to Bacula version 2.0.3 with:
-
- cd <bacula-source>
- patch -p0 <2.0.3-maxwaittime.patch
- make
- ...
- make install
-
-
-
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (revision 4349)
-+++ src/dird/job.c (working copy)
-@@ -481,7 +481,6 @@
- static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
- {
- bool cancel = false;
-- bool ok_to_cancel = false;
- JOB *job = jcr->job;
-
- if (job_canceled(jcr)) {
-@@ -493,69 +492,18 @@
- }
- if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
-- ok_to_cancel = true;
-+ cancel = true;
- } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
-- ok_to_cancel = true;
-+ cancel = true;
- } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
-- ok_to_cancel = true;
-+ cancel = true;
- } else if (job->MaxWaitTime != 0 &&
- (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
-- ok_to_cancel = true;
-- }
-- if (!ok_to_cancel) {
-- return false;
-- }
--
--/*
-- * I don't see the need for all this -- kes 17Dec06
-- */
--#ifdef xxx
-- Dmsg3(800, "Job %d (%s): MaxWaitTime of %d seconds exceeded, "
-- "checking status\n",
-- jcr->JobId, jcr->Job, job->MaxWaitTime);
-- switch (jcr->JobStatus) {
-- case JS_Created:
-- case JS_Blocked:
-- case JS_WaitFD:
-- case JS_WaitSD:
-- case JS_WaitStoreRes:
-- case JS_WaitClientRes:
-- case JS_WaitJobRes:
-- case JS_WaitPriority:
-- case JS_WaitMaxJobs:
-- case JS_WaitStartTime:
- cancel = true;
-- Dmsg0(200, "JCR blocked in #1\n");
-- break;
-- case JS_Running:
-- Dmsg0(800, "JCR running, checking SD status\n");
-- switch (jcr->SDJobStatus) {
-- case JS_WaitMount:
-- case JS_WaitMedia:
-- case JS_WaitFD:
-- cancel = true;
-- Dmsg0(800, "JCR blocked in #2\n");
-- break;
-- default:
-- Dmsg0(800, "JCR not blocked in #2\n");
-- break;
-- }
-- break;
-- case JS_Terminated:
-- case JS_ErrorTerminated:
-- case JS_Canceled:
-- case JS_FatalError:
-- Dmsg0(800, "JCR already dead in #3\n");
-- break;
-- default:
-- Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
-- jcr->JobStatus);
- }
-- Dmsg3(800, "MaxWaitTime result: %scancel JCR %p (%s)\n",
-- cancel ? "" : "do not ", jcr, jcr->Job);
--#endif
-+
- return cancel;
- }
-
-@@ -574,36 +522,6 @@
- return false;
- }
-
--#ifdef xxx
-- switch (jcr->JobStatus) {
-- case JS_Created:
-- case JS_Running:
-- case JS_Blocked:
-- case JS_WaitFD:
-- case JS_WaitSD:
-- case JS_WaitStoreRes:
-- case JS_WaitClientRes:
-- case JS_WaitJobRes:
-- case JS_WaitPriority:
-- case JS_WaitMaxJobs:
-- case JS_WaitStartTime:
-- case JS_Differences:
-- cancel = true;
-- break;
-- case JS_Terminated:
-- case JS_ErrorTerminated:
-- case JS_Canceled:
-- case JS_FatalError:
-- cancel = false;
-- break;
-- default:
-- Jmsg1(jcr, M_ERROR, 0, _("Unhandled job status code %d\n"),
-- jcr->JobStatus);
-- }
--
-- Dmsg3(200, "MaxRunTime result: %scancel JCR %p (%s)\n",
-- cancel ? "" : "do not ", jcr, jcr->Job);
--#endif
- return true;
- }
-
+++ /dev/null
-
- This patch should fix bug #812 where the DST time shift was
- incorrectly handled. This patch was submitted by Martin Simmons.
- Apply it to Bacula version 2.0.3 with:
-
- cd <bacula-source>
- patch -p0 <2.0.3-scheduler-next-hour.patch
- make
- ...
- make install
-
-Index: src/dird/scheduler.c
-===================================================================
---- src/dird/scheduler.c (revision 4445)
-+++ src/dird/scheduler.c (working copy)
-@@ -175,11 +175,11 @@
- }
- /* Recheck at least once per minute */
- bmicrosleep((next_check_secs < twait)?next_check_secs:twait, 0);
-- /* Attempt to handle clock shift from/to daylight savings time
-+ /* Attempt to handle clock shift (but not daylight savings time changes)
- * we allow a skew of 10 seconds before invalidating everything.
- */
- now = time(NULL);
-- if (now < prev+10 || now > (prev+next_check_secs+10)) {
-+ if (now < prev-10 || now > (prev+next_check_secs+10)) {
- schedules_invalidated = true;
- }
- }
-@@ -284,6 +284,9 @@
- wom = mday / 7;
- woy = tm_woy(now); /* get week of year */
-
-+ Dmsg7(dbglvl, "now = %x: h=%d m=%d md=%d wd=%d wom=%d woy=%d\n",
-+ now, hour, month, mday, wday, wom, woy);
-+
- /*
- * Compute values for next hour from now.
- * We do this to be sure we don't miss a job while
-@@ -299,6 +302,9 @@
- nh_wom = nh_mday / 7;
- nh_woy = tm_woy(now); /* get week of year */
-
-+ Dmsg7(dbglvl, "nh = %x: h=%d m=%d md=%d wd=%d wom=%d woy=%d\n",
-+ next_hour, nh_hour, nh_month, nh_mday, nh_wday, nh_wom, nh_woy);
-+
- /* Loop through all jobs */
- LockRes();
- foreach_res(job, R_JOB) {
-@@ -351,24 +357,20 @@
-
- Dmsg3(dbglvl, "run@%p: run_now=%d run_nh=%d\n", run, run_now, run_nh);
-
-- /* find time (time_t) job is to be run */
-- (void)localtime_r(&now, &tm); /* reset tm structure */
-- tm.tm_min = run->minute; /* set run minute */
-- tm.tm_sec = 0; /* zero secs */
-- if (run_now) {
-- runtime = mktime(&tm);
-- add_job(job, run, now, runtime);
-- }
-- /* If job is to be run in the next hour schedule it */
-- if (run_nh) {
-- /* Set correct values */
-- tm.tm_hour = nh_hour;
-- tm.tm_mday = nh_mday + 1; /* fixup because we biased for tests above */
-- tm.tm_mon = nh_month;
-- tm.tm_year = nh_year;
-- runtime = mktime(&tm);
-- add_job(job, run, now, runtime);
-- }
-+ if (run_now || run_nh) {
-+ /* find time (time_t) job is to be run */
-+ (void)localtime_r(&now, &tm); /* reset tm structure */
-+ tm.tm_min = run->minute; /* set run minute */
-+ tm.tm_sec = 0; /* zero secs */
-+ runtime = mktime(&tm);
-+ if (run_now) {
-+ add_job(job, run, now, runtime);
-+ }
-+ /* If job is to be run in the next hour schedule it */
-+ if (run_nh) {
-+ add_job(job, run, now, runtime + 3600);
-+ }
-+ }
- }
- }
- UnlockRes();
+++ /dev/null
-
-This patch should fix the spurious connection drops that fail jobs
-as reported in bug #888.
-Apply it to version 2.0.3 (possibly earlier versions of 2.0) with:
-
- cd <bacula-source>
- patch -p0 <2.0.3-tls-disconnect.patch
- make
- ...
- make install
-
-Index: src/lib/tls.c
-===================================================================
---- src/lib/tls.c (revision 4668)
-+++ src/lib/tls.c (working copy)
-@@ -540,14 +540,6 @@
- * The first time to initiate the shutdown handshake, and the second to
- * receive the peer's reply.
- *
-- * However, it is valid to close the SSL connection after the initial
-- * shutdown notification is sent to the peer, without waiting for the
-- * peer's reply, as long as you do not plan to re-use that particular
-- * SSL connection object.
-- *
-- * Because we do not re-use SSL connection objects, I do not bother
-- * calling SSL_shutdown a second time.
-- *
- * In addition, if the underlying socket is blocking, SSL_shutdown()
- * will not return until the current stage of the shutdown process has
- * completed or an error has occured. By setting the socket blocking
-@@ -560,6 +552,10 @@
- flags = bnet_set_blocking(bsock);
-
- err = SSL_shutdown(bsock->tls->openssl);
-+ if (err == 0) {
-+ /* Finish up the closing */
-+ err = SSL_shutdown(bsock->tls->openssl);
-+ }
-
- switch (SSL_get_error(bsock->tls->openssl, err)) {
- case SSL_ERROR_NONE:
-@@ -574,8 +570,6 @@
- break;
- }
-
-- /* Restore saved flags */
-- bnet_restore_blocking(bsock, flags);
- }
-
- /* Does all the manual labor for tls_bsock_readn() and tls_bsock_writen() */
+++ /dev/null
-This patch should fix the problem reported in bug #803 where a Verify
-job select the JobId to verified at schedule time rather than at runtime.
-This makes it difficult or impossible to schedule a verify just after
-a backup.
-
-Apply this patch to Bacula version 2.0.3 (probably 2.0.2 as well) with:
-
- cd <bacula-source>
- patch -p0 <2.0.3-verify.patch
- make
- ...
- make install
-
-Index: src/dird/verify.c
-===================================================================
---- src/dird/verify.c (revision 4353)
-+++ src/dird/verify.c (working copy)
-@@ -1,22 +1,7 @@
- /*
-- *
-- * Bacula Director -- verify.c -- responsible for running file verification
-- *
-- * Kern Sibbald, October MM
-- *
-- * Basic tasks done here:
-- * Open DB
-- * Open connection with File daemon and pass him commands
-- * to do the verify.
-- * When the File daemon sends the attributes, compare them to
-- * what is in the DB.
-- *
-- * Version $Id$
-- */
--/*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2007 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.
-@@ -40,6 +25,21 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ *
-+ * Bacula Director -- verify.c -- responsible for running file verification
-+ *
-+ * Kern Sibbald, October MM
-+ *
-+ * Basic tasks done here:
-+ * Open DB
-+ * Open connection with File daemon and pass him commands
-+ * to do the verify.
-+ * When the File daemon sends the attributes, compare them to
-+ * what is in the DB.
-+ *
-+ * Version $Id$
-+ */
-
-
- #include "bacula.h"
-@@ -66,6 +66,22 @@
- */
- bool do_verify_init(JCR *jcr)
- {
-+ return true;
-+}
-+
-+
-+/*
-+ * Do a verification of the specified files against the Catlaog
-+ *
-+ * Returns: false on failure
-+ * true on success
-+ */
-+bool do_verify(JCR *jcr)
-+{
-+ const char *level;
-+ BSOCK *fd;
-+ int stat;
-+ char ed1[100];
- JOB_DBR jr;
- JobId_t verify_jobid = 0;
- const char *Name;
-@@ -74,12 +90,16 @@
-
- memset(&jcr->previous_jr, 0, sizeof(jcr->previous_jr));
-
-- Dmsg1(9, "bdird: created client %s record\n", jcr->client->hdr.name);
--
- /*
-- * Find JobId of last job that ran. E.g.
-- * for VERIFY_CATALOG we want the JobId of the last INIT.
-- * for VERIFY_VOLUME_TO_CATALOG, we want the JobId of the
-+ * Find JobId of last job that ran. Note, we do this when
-+ * the job actually starts running, not at schedule time,
-+ * so that we find the last job that terminated before
-+ * this job runs rather than before it is scheduled. This
-+ * permits scheduling a Backup and Verify at the same time,
-+ * but with the Verify at a lower priority.
-+ *
-+ * For VERIFY_CATALOG we want the JobId of the last INIT.
-+ * For VERIFY_VOLUME_TO_CATALOG, we want the JobId of the
- * last backup Job.
- */
- if (jcr->JobLevel == L_VERIFY_CATALOG ||
-@@ -89,7 +109,7 @@
- if (jcr->verify_job &&
- (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ||
- jcr->JobLevel == L_VERIFY_DISK_TO_CATALOG)) {
-- Name = jcr->verify_job->hdr.name;
-+ Name = jcr->verify_job->name();
- } else {
- Name = NULL;
- }
-@@ -149,23 +169,7 @@
- jcr->fileset = jcr->verify_job->fileset;
- }
- Dmsg2(100, "ClientId=%u JobLevel=%c\n", jcr->previous_jr.ClientId, jcr->JobLevel);
-- return true;
--}
-
--
--/*
-- * Do a verification of the specified files against the Catlaog
-- *
-- * Returns: false on failure
-- * true on success
-- */
--bool do_verify(JCR *jcr)
--{
-- const char *level;
-- BSOCK *fd;
-- int stat;
-- char ed1[100];
--
- if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
- Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
- return false;
+++ /dev/null
-Index: fd_cmds.c
-===================================================================
---- fd_cmds.c (.../tags/Release-2.2.0/bacula/src/stored) (revision 5508)
-+++ fd_cmds.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -1,18 +1,4 @@
- /*
-- * This file handles commands from the File daemon.
-- *
-- * Kern Sibbald, MM
-- *
-- * We get here because the Director has initiated a Job with
-- * the Storage daemon, then done the same with the File daemon,
-- * then when the Storage daemon receives a proper connection from
-- * the File daemon, control is passed here to handle the
-- * subsequent File daemon commands.
-- *
-- * Version $Id$
-- *
-- */
--/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-@@ -39,6 +25,20 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ * This file handles commands from the File daemon.
-+ *
-+ * Kern Sibbald, MM
-+ *
-+ * We get here because the Director has initiated a Job with
-+ * the Storage daemon, then done the same with the File daemon,
-+ * then when the Storage daemon receives a proper connection from
-+ * the File daemon, control is passed here to handle the
-+ * subsequent File daemon commands.
-+ *
-+ * Version $Id$
-+ *
-+ */
-
- #include "bacula.h"
- #include "stored.h"
-@@ -120,7 +120,7 @@
-
- dir->set_jcr(jcr);
- Dmsg1(120, "Start run Job=%s\n", jcr->Job);
-- bnet_fsend(dir, Job_start, jcr->Job);
-+ dir->fsend(Job_start, jcr->Job);
- jcr->start_time = time(NULL);
- jcr->run_time = jcr->start_time;
- set_jcr_job_status(jcr, JS_Running);
-@@ -130,9 +130,9 @@
- dequeue_messages(jcr); /* send any queued messages */
- set_jcr_job_status(jcr, JS_Terminated);
- generate_daemon_event(jcr, "JobEnd");
-- bnet_fsend(dir, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
-+ dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
- edit_uint64(jcr->JobBytes, ec1));
-- bnet_sig(dir, BNET_EOD); /* send EOD to Director daemon */
-+ dir->signal(BNET_EOD); /* send EOD to Director daemon */
- return;
- }
-
-@@ -150,7 +150,7 @@
- int stat;
-
- /* Read command coming from the File daemon */
-- stat = bnet_recv(fd);
-+ stat = fd->recv();
- if (is_bnet_stop(fd)) { /* hardeof or error */
- break; /* connection terminated */
- }
-@@ -171,11 +171,11 @@
- }
- if (!found) { /* command not found */
- Dmsg1(110, "<filed: Command not found: %s\n", fd->msg);
-- bnet_fsend(fd, ferrmsg);
-+ fd->fsend(ferrmsg);
- break;
- }
- }
-- bnet_sig(fd, BNET_TERMINATE); /* signal to FD job is done */
-+ fd->signal(BNET_TERMINATE); /* signal to FD job is done */
- }
-
- /*
-@@ -195,10 +195,10 @@
- return true;
- } else {
- bnet_suppress_error_messages(fd, 1); /* ignore errors at this point */
-- bnet_fsend(fd, ERROR_append);
-+ fd->fsend(ERROR_append);
- }
- } else {
-- bnet_fsend(fd, NOT_opened);
-+ fd->fsend(NOT_opened);
- }
- return false;
- }
-@@ -209,11 +209,11 @@
-
- Dmsg1(120, "store<file: %s", fd->msg);
- if (!jcr->session_opened) {
-- bnet_fsend(fd, NOT_opened);
-+ fd->fsend(NOT_opened);
- return false;
- }
- set_jcr_job_status(jcr, JS_Terminated);
-- return bnet_fsend(fd, OK_end);
-+ return fd->fsend(OK_end);
- }
-
-
-@@ -227,14 +227,14 @@
-
- Dmsg1(120, "Append open session: %s", fd->msg);
- if (jcr->session_opened) {
-- bnet_fsend(fd, NO_open);
-+ fd->fsend(NO_open);
- return false;
- }
-
- jcr->session_opened = true;
-
- /* Send "Ticket" to File Daemon */
-- bnet_fsend(fd, OK_open, jcr->VolSessionId);
-+ fd->fsend(OK_open, jcr->VolSessionId);
- Dmsg1(110, ">filed: %s", fd->msg);
-
- return true;
-@@ -251,14 +251,14 @@
-
- Dmsg1(120, "<filed: %s", fd->msg);
- if (!jcr->session_opened) {
-- bnet_fsend(fd, NOT_opened);
-+ fd->fsend(NOT_opened);
- return false;
- }
- /* Send final statistics to File daemon */
-- bnet_fsend(fd, OK_close, jcr->JobStatus);
-+ fd->fsend(OK_close, jcr->JobStatus);
- Dmsg1(120, ">filed: %s", fd->msg);
-
-- bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */
-+ fd->signal(BNET_EOD); /* send EOD to File daemon */
-
- jcr->session_opened = false;
- return true;
-@@ -279,7 +279,7 @@
- Dmsg1(120, "<bfiled: %s", fd->msg);
- return do_read_data(jcr);
- } else {
-- bnet_fsend(fd, NOT_opened);
-+ fd->fsend(NOT_opened);
- return false;
- }
- }
-@@ -296,7 +296,7 @@
-
- Dmsg1(120, "%s\n", fd->msg);
- if (jcr->session_opened) {
-- bnet_fsend(fd, NO_open);
-+ fd->fsend(NO_open);
- return false;
- }
-
-@@ -304,7 +304,7 @@
- &jcr->read_VolSessionTime, &jcr->read_StartFile, &jcr->read_EndFile,
- &jcr->read_StartBlock, &jcr->read_EndBlock) == 7) {
- if (jcr->session_opened) {
-- bnet_fsend(fd, NOT_opened);
-+ fd->fsend(NOT_opened);
- return false;
- }
- Dmsg4(100, "read_open_session got: JobId=%d Vol=%s VolSessId=%ld VolSessT=%ld\n",
-@@ -319,7 +319,7 @@
- jcr->JobType = JT_RESTORE;
-
- /* Send "Ticket" to File Daemon */
-- bnet_fsend(fd, OK_open, jcr->VolSessionId);
-+ fd->fsend(OK_open, jcr->VolSessionId);
- Dmsg1(110, ">filed: %s", fd->msg);
-
- return true;
-@@ -357,7 +357,7 @@
- goto bail_out;
- }
- Dmsg0(10, "=== Bootstrap file ===\n");
-- while (bnet_recv(sock) >= 0) {
-+ while (sock->recv() >= 0) {
- Dmsg1(10, "%s", sock->msg);
- fputs(sock->msg, bs);
- }
-@@ -378,10 +378,10 @@
- free_pool_memory(jcr->RestoreBootstrap);
- jcr->RestoreBootstrap = NULL;
- if (!ok) {
-- bnet_fsend(sock, ERROR_bootstrap);
-+ sock->fsend(ERROR_bootstrap);
- return false;
- }
-- return bnet_fsend(sock, OK_bootstrap);
-+ return sock->fsend(OK_bootstrap);
- }
-
-
-@@ -395,14 +395,14 @@
-
- Dmsg1(120, "Read close session: %s\n", fd->msg);
- if (!jcr->session_opened) {
-- bnet_fsend(fd, NOT_opened);
-+ fd->fsend(NOT_opened);
- return false;
- }
-- /* Send final statistics to File daemon */
-- bnet_fsend(fd, OK_close);
-+ /* Send final close msg to File daemon */
-+ fd->fsend(OK_close, jcr->JobStatus);
- Dmsg1(160, ">filed: %s\n", fd->msg);
-
-- bnet_sig(fd, BNET_EOD); /* send EOD to File daemon */
-+ fd->signal(BNET_EOD); /* send EOD to File daemon */
-
- jcr->session_opened = false;
- return true;
-Index: stored_conf.c
-===================================================================
---- stored_conf.c (.../tags/Release-2.2.0/bacula/src/stored) (revision 5508)
-+++ stored_conf.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -75,7 +75,7 @@
- {"piddirectory", store_dir, ITEM(res_store.pid_directory), 0, ITEM_REQUIRED, 0},
- {"subsysdirectory", store_dir, ITEM(res_store.subsys_directory), 0, 0, 0},
- {"scriptsdirectory", store_dir, ITEM(res_store.scripts_directory), 0, 0, 0},
-- {"maximumconcurrentjobs", store_pint, ITEM(res_store.max_concurrent_jobs), 0, ITEM_DEFAULT, 10},
-+ {"maximumconcurrentjobs", store_pint, ITEM(res_store.max_concurrent_jobs), 0, ITEM_DEFAULT, 20},
- {"heartbeatinterval", store_time, ITEM(res_store.heartbeat_interval), 0, ITEM_DEFAULT, 0},
- {"tlsenable", store_bit, ITEM(res_store.tls_enable), 1, 0, 0},
- {"tlsrequire", store_bit, ITEM(res_store.tls_require), 1, 0, 0},
-Index: bscan.c
-===================================================================
---- bscan.c (.../tags/Release-2.2.0/bacula/src/stored) (revision 5508)
-+++ bscan.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -120,7 +120,7 @@
- " -m update media info in database\n"
- " -n <name> specify the database name (default bacula)\n"
- " -u <user> specify database user name (default bacula)\n"
--" -P <password specify database password (default none)\n"
-+" -P <password> specify database password (default none)\n"
- " -h <host> specify database host (default NULL)\n"
- " -p proceed inspite of I/O errors\n"
- " -r list records\n"
-@@ -326,6 +326,7 @@
- mdcr->StartFile = dcr->StartFile;
- mdcr->EndBlock = dcr->EndBlock;
- mdcr->EndFile = dcr->EndFile;
-+ mdcr->VolMediaId = dcr->VolMediaId;
- mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex;
- if (!create_jobmedia_record(db, mjcr)) {
- Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
-@@ -476,6 +477,7 @@
- dcr->VolFirstIndex = dcr->FileIndex = 0;
- dcr->StartBlock = dcr->EndBlock = 0;
- dcr->StartFile = dcr->EndFile = 0;
-+ dcr->VolMediaId = 0;
- }
-
- Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName);
-@@ -1177,6 +1179,7 @@
-
- dcr->EndBlock = dev->EndBlock;
- dcr->EndFile = dev->EndFile;
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
-
- memset(&jmr, 0, sizeof(jmr));
- jmr.JobId = mjcr->JobId;
-Index: askdir.c
-===================================================================
---- askdir.c (.../tags/Release-2.2.0/bacula/src/stored) (revision 5508)
-+++ askdir.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -398,7 +398,7 @@
- dcr->StartFile, dcr->EndFile,
- dcr->StartBlock, dcr->EndBlock,
- dcr->Copy, dcr->Stripe,
-- edit_uint64(dcr->dev->VolCatInfo.VolMediaId, ed1));
-+ edit_uint64(dcr->VolMediaId, ed1));
- Dmsg1(100, ">dird: %s", dir->msg);
- if (bnet_recv(dir) <= 0) {
- Dmsg0(190, "create_jobmedia error bnet_recv\n");
-Index: dev.h
-===================================================================
---- dev.h (.../tags/Release-2.2.0/bacula/src/stored) (revision 5508)
-+++ dev.h (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -447,6 +447,7 @@
- uint32_t StartFile; /* Start write file */
- uint32_t StartBlock; /* Start write block */
- uint32_t EndBlock; /* Ending block written */
-+ int64_t VolMediaId; /* MediaId */
- int64_t job_spool_size; /* Current job spool size */
- int64_t max_job_spool_size; /* Max job spool size */
- char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
-Index: block.c
-===================================================================
---- block.c (.../tags/Release-2.2.0/bacula/src/stored) (revision 5508)
-+++ block.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -611,6 +611,7 @@
- dev->block_num = dcr->EndBlock;
- dev->file = dcr->EndFile;
- }
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
- if (dcr->VolFirstIndex == 0 && block->FirstIndex > 0) {
- dcr->VolFirstIndex = block->FirstIndex;
- }
-@@ -1098,6 +1099,7 @@
- dev->block_num = dcr->EndBlock;
- dev->file = dcr->EndFile;
- }
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
- dev->file_addr += block->read_len;
- dev->file_size += block->read_len;
-
+++ /dev/null
-Index: fd_cmds.c
-===================================================================
---- fd_cmds.c (.../tags/Release-2.2.1/bacula/src/stored) (revision 5508)
-+++ fd_cmds.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -1,18 +1,4 @@
- /*
-- * This file handles commands from the File daemon.
-- *
-- * Kern Sibbald, MM
-- *
-- * We get here because the Director has initiated a Job with
-- * the Storage daemon, then done the same with the File daemon,
-- * then when the Storage daemon receives a proper connection from
-- * the File daemon, control is passed here to handle the
-- * subsequent File daemon commands.
-- *
-- * Version $Id$
-- *
-- */
--/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-@@ -39,6 +25,20 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ * This file handles commands from the File daemon.
-+ *
-+ * Kern Sibbald, MM
-+ *
-+ * We get here because the Director has initiated a Job with
-+ * the Storage daemon, then done the same with the File daemon,
-+ * then when the Storage daemon receives a proper connection from
-+ * the File daemon, control is passed here to handle the
-+ * subsequent File daemon commands.
-+ *
-+ * Version $Id$
-+ *
-+ */
-
- #include "bacula.h"
- #include "stored.h"
-Index: bscan.c
-===================================================================
---- bscan.c (.../tags/Release-2.2.1/bacula/src/stored) (revision 5508)
-+++ bscan.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -326,6 +326,7 @@
- mdcr->StartFile = dcr->StartFile;
- mdcr->EndBlock = dcr->EndBlock;
- mdcr->EndFile = dcr->EndFile;
-+ mdcr->VolMediaId = dcr->VolMediaId;
- mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex;
- if (!create_jobmedia_record(db, mjcr)) {
- Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
-@@ -476,6 +477,7 @@
- dcr->VolFirstIndex = dcr->FileIndex = 0;
- dcr->StartBlock = dcr->EndBlock = 0;
- dcr->StartFile = dcr->EndFile = 0;
-+ dcr->VolMediaId = 0;
- }
-
- Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName);
-@@ -1177,6 +1179,7 @@
-
- dcr->EndBlock = dev->EndBlock;
- dcr->EndFile = dev->EndFile;
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
-
- memset(&jmr, 0, sizeof(jmr));
- jmr.JobId = mjcr->JobId;
-Index: askdir.c
-===================================================================
---- askdir.c (.../tags/Release-2.2.1/bacula/src/stored) (revision 5508)
-+++ askdir.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -398,7 +398,7 @@
- dcr->StartFile, dcr->EndFile,
- dcr->StartBlock, dcr->EndBlock,
- dcr->Copy, dcr->Stripe,
-- edit_uint64(dcr->dev->VolCatInfo.VolMediaId, ed1));
-+ edit_uint64(dcr->VolMediaId, ed1));
- Dmsg1(100, ">dird: %s", dir->msg);
- if (bnet_recv(dir) <= 0) {
- Dmsg0(190, "create_jobmedia error bnet_recv\n");
-Index: dev.h
-===================================================================
---- dev.h (.../tags/Release-2.2.1/bacula/src/stored) (revision 5508)
-+++ dev.h (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -447,6 +447,7 @@
- uint32_t StartFile; /* Start write file */
- uint32_t StartBlock; /* Start write block */
- uint32_t EndBlock; /* Ending block written */
-+ int64_t VolMediaId; /* MediaId */
- int64_t job_spool_size; /* Current job spool size */
- int64_t max_job_spool_size; /* Max job spool size */
- char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
-Index: block.c
-===================================================================
---- block.c (.../tags/Release-2.2.1/bacula/src/stored) (revision 5508)
-+++ block.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -611,6 +611,7 @@
- dev->block_num = dcr->EndBlock;
- dev->file = dcr->EndFile;
- }
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
- if (dcr->VolFirstIndex == 0 && block->FirstIndex > 0) {
- dcr->VolFirstIndex = block->FirstIndex;
- }
-@@ -1098,6 +1099,7 @@
- dev->block_num = dcr->EndBlock;
- dev->file = dcr->EndFile;
- }
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
- dev->file_addr += block->read_len;
- dev->file_size += block->read_len;
-
+++ /dev/null
-Index: fd_cmds.c
-===================================================================
---- fd_cmds.c (.../tags/Release-2.2.2/bacula/src/stored) (revision 5508)
-+++ fd_cmds.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -1,18 +1,4 @@
- /*
-- * This file handles commands from the File daemon.
-- *
-- * Kern Sibbald, MM
-- *
-- * We get here because the Director has initiated a Job with
-- * the Storage daemon, then done the same with the File daemon,
-- * then when the Storage daemon receives a proper connection from
-- * the File daemon, control is passed here to handle the
-- * subsequent File daemon commands.
-- *
-- * Version $Id$
-- *
-- */
--/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-@@ -39,6 +25,20 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ * This file handles commands from the File daemon.
-+ *
-+ * Kern Sibbald, MM
-+ *
-+ * We get here because the Director has initiated a Job with
-+ * the Storage daemon, then done the same with the File daemon,
-+ * then when the Storage daemon receives a proper connection from
-+ * the File daemon, control is passed here to handle the
-+ * subsequent File daemon commands.
-+ *
-+ * Version $Id$
-+ *
-+ */
-
- #include "bacula.h"
- #include "stored.h"
-Index: bscan.c
-===================================================================
---- bscan.c (.../tags/Release-2.2.2/bacula/src/stored) (revision 5508)
-+++ bscan.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -326,6 +326,7 @@
- mdcr->StartFile = dcr->StartFile;
- mdcr->EndBlock = dcr->EndBlock;
- mdcr->EndFile = dcr->EndFile;
-+ mdcr->VolMediaId = dcr->VolMediaId;
- mjcr->read_dcr->VolLastIndex = dcr->VolLastIndex;
- if (!create_jobmedia_record(db, mjcr)) {
- Pmsg2(000, _("Could not create JobMedia record for Volume=%s Job=%s\n"),
-@@ -476,6 +477,7 @@
- dcr->VolFirstIndex = dcr->FileIndex = 0;
- dcr->StartBlock = dcr->EndBlock = 0;
- dcr->StartFile = dcr->EndFile = 0;
-+ dcr->VolMediaId = 0;
- }
-
- Pmsg1(000, _("VOL_LABEL: OK for Volume: %s\n"), mr.VolumeName);
-@@ -1177,6 +1179,7 @@
-
- dcr->EndBlock = dev->EndBlock;
- dcr->EndFile = dev->EndFile;
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
-
- memset(&jmr, 0, sizeof(jmr));
- jmr.JobId = mjcr->JobId;
-Index: askdir.c
-===================================================================
---- askdir.c (.../tags/Release-2.2.2/bacula/src/stored) (revision 5508)
-+++ askdir.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -398,7 +398,7 @@
- dcr->StartFile, dcr->EndFile,
- dcr->StartBlock, dcr->EndBlock,
- dcr->Copy, dcr->Stripe,
-- edit_uint64(dcr->dev->VolCatInfo.VolMediaId, ed1));
-+ edit_uint64(dcr->VolMediaId, ed1));
- Dmsg1(100, ">dird: %s", dir->msg);
- if (bnet_recv(dir) <= 0) {
- Dmsg0(190, "create_jobmedia error bnet_recv\n");
-Index: dev.h
-===================================================================
---- dev.h (.../tags/Release-2.2.2/bacula/src/stored) (revision 5508)
-+++ dev.h (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -447,6 +447,7 @@
- uint32_t StartFile; /* Start write file */
- uint32_t StartBlock; /* Start write block */
- uint32_t EndBlock; /* Ending block written */
-+ int64_t VolMediaId; /* MediaId */
- int64_t job_spool_size; /* Current job spool size */
- int64_t max_job_spool_size; /* Max job spool size */
- char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
-Index: block.c
-===================================================================
---- block.c (.../tags/Release-2.2.2/bacula/src/stored) (revision 5508)
-+++ block.c (.../branches/Branch-2.2/bacula/src/stored) (revision 5508)
-@@ -611,6 +611,7 @@
- dev->block_num = dcr->EndBlock;
- dev->file = dcr->EndFile;
- }
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
- if (dcr->VolFirstIndex == 0 && block->FirstIndex > 0) {
- dcr->VolFirstIndex = block->FirstIndex;
- }
-@@ -1098,6 +1099,7 @@
- dev->block_num = dcr->EndBlock;
- dev->file = dcr->EndFile;
- }
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
- dev->file_addr += block->read_len;
- dev->file_size += block->read_len;
-
+++ /dev/null
- This patch corrects a bug where the last volume of a migration
- job is incorrectly found producing an error. This fixes bug #936.
- Apply the patch to 2.2.3 (and possibly earlier 2.2.x versions) with:
-
- cd <bacula-source>
- patch -p0 <2.2.3-migrate-vol.patch
- ./configure (your options)
- make
- ...
- make install
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 5507)
-+++ src/dird/migrate.c (working copy)
-@@ -1098,8 +1098,10 @@
- if (mig_jcr->VolumeName[0]) {
- /* Find last volume name. Multiple vols are separated by | */
- char *p = strrchr(mig_jcr->VolumeName, '|');
-- if (!p) {
-- p = mig_jcr->VolumeName;
-+ if (p) {
-+ p++; /* skip | */
-+ } else {
-+ p = mig_jcr->VolumeName; /* no |, take full name */
- }
- bstrncpy(mr.VolumeName, p, sizeof(mr.VolumeName));
- if (!db_get_media_record(jcr, jcr->db, &mr)) {
+++ /dev/null
-
- This patch was supplied by Landon Fuller and corrects a bug that
- caused high CPU usage when connecting from bconsole to the Director.
- This fixes bug #944.
-
- Apply this patch to version 2.2.3 (it should work with any 2.2.x
- version with:
-
- cd <bacula-source>
- patch -p0 <2.2.3-tls.patch
- ./configure (your options)
- make
- ...
- make install
-
-Index: src/lib/tls.c
-===================================================================
---- src/lib/tls.c (revision 5507)
-+++ src/lib/tls.c (working copy)
-@@ -622,13 +622,21 @@
- break;
-
- case SSL_ERROR_WANT_READ:
-+ /* If we timeout on a select, this will be unset */
-+ FD_SET((unsigned)bsock->m_fd, &fdset);
-+ tv.tv_sec = 10;
-+ tv.tv_usec = 0;
-+ /* Block until we can read */
-+ select(fdmax, &fdset, NULL, NULL, &tv);
-+ break;
-+
- case SSL_ERROR_WANT_WRITE:
- /* If we timeout on a select, this will be unset */
- FD_SET((unsigned)bsock->m_fd, &fdset);
- tv.tv_sec = 10;
- tv.tv_usec = 0;
-- /* Block until we can read or write */
-- select(fdmax, NULL, &fdset, &fdset, &tv);
-+ /* Block until we can write */
-+ select(fdmax, NULL, &fdset, NULL, &tv);
- break;
-
- case SSL_ERROR_ZERO_RETURN:
+++ /dev/null
-
- This patch fixes bug #954.
- WEOF on non-appendable error when trying to label a tape with ANSI labels turned on.
-
- Apply it to version 2.2.4 (possibly earlier versions with):
-
- cd <bacula-source>
- patch -p0 <2.2.4-verify.patch
- ./configure (your options)
- make
- ...
- make install
-
-Index: block.c
-===================================================================
---- src/stored/block.c (revision 5615)
-+++ src/stored/block.c (revision 5615)
-@@ -273,6 +273,7 @@
- dev->dev_errno = EIO;
- Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Wanted ID: \"%s\", got \"%s\". Buffer discarded.\n"),
- dev->file, dev->block_num, BLKHDR2_ID, Id);
-+ Dmsg1(50, "%s", dev->errmsg);
- if (block->read_errors == 0 || verbose >= 2) {
- Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
- }
-@@ -1008,8 +1009,19 @@
- dev->set_ateof();
- return false; /* return eof */
- }
-+
- /* Continue here for successful read */
-+
- block->read_len = stat; /* save length read */
-+ if (dev->at_eof() && block->read_len == 80 &&
-+ (dcr->VolCatInfo.LabelType != B_BACULA_LABEL ||
-+ dcr->device->label_type != B_BACULA_LABEL)) {
-+ /* ***FIXME*** should check label */
-+ Dmsg2(100, "Ignore 80 byte ANSI label at %u:%u\n", dev->file, dev->block_num);
-+ dev->clear_eof();
-+ goto reread; /* skip ANSI/IBM label */
-+ }
-+
- if (block->read_len < BLKHDR2_LENGTH) {
- dev->dev_errno = EIO;
- Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Very short block of %d bytes on device %s discarded.\n"),
-
-Index: label.c
-===================================================================
---- src/stored/label.c (revision 5602)
-+++ src/stored/label.c (working copy)
-@@ -119,7 +119,6 @@
- bstrncpy(dev->VolHdr.Id, "**error**", sizeof(dev->VolHdr.Id));
-
- /* Read ANSI/IBM label if so requested */
--
- want_ansi_label = dcr->VolCatInfo.LabelType != B_BACULA_LABEL ||
- dcr->device->label_type != B_BACULA_LABEL;
- if (want_ansi_label || dev->has_cap(CAP_CHECKLABELS)) {
-@@ -344,6 +343,9 @@
- }
- }
-
-+ /* Temporarily mark in append state to enable writing */
-+ dev->set_append();
-+
- /* Create PRE_LABEL or VOL_LABEL if DVD */
- create_volume_label(dev, VolName, PoolName, dvdnow);
-
-@@ -364,8 +366,6 @@
- create_volume_label_record(dcr, dcr->rec);
- dcr->rec->Stream = 0;
-
-- /* Temporarily mark in append state to enable writing */
-- dev->set_append();
- if (!write_record_to_block(dcr->block, dcr->rec)) {
- Dmsg2(130, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->print_errmsg());
- goto bail_out;
+++ /dev/null
-
- This patch fixes a race condition where a Job is terminating at the same
- time that another job reaches the end of Volume. In that case, sometimes
- the last block or two are not written to the Volume. This seems to be
- relatively rare, but does result in data loss. This fixes bug #964.
-
- Apply the patch to Bacula version 2.2.4 (or possibly any previous 2.2.x
- version) with:
-
- cd <bacula-source>
- patch -p0 <2.2.4-lost-block.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-Index: src/stored/append.c
-===================================================================
---- src/stored/append.c (revision 5602)
-+++ src/stored/append.c (working copy)
-@@ -287,7 +287,7 @@
- * Check if we can still write. This may not be the case
- * if we are at the end of the tape or we got a fatal I/O error.
- */
-- if (dev->can_write()) {
-+ if (ok || dev->can_write()) {
- if (!write_session_label(dcr, EOS_LABEL)) {
- Jmsg1(jcr, M_FATAL, 0, _("Error writting end session label. ERR=%s\n"),
- dev->bstrerror());
+++ /dev/null
-
- This patch resolves a command parser issue
- causing a director segfault when using something
- like "run job 1 2"
-
- Apply to version 2.2.4 (and perhaps older 2.2.x versions) with
-
- cd <bacula-source>
- patch -p0 <2.2.4-parse-command.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-Index: src/dird/ua_run.c
-===================================================================
---- src/dird/ua_run.c (révision 5616)
-+++ src/dird/ua_run.c (copie de travail)
-@@ -933,7 +933,7 @@
- /* Note, yes and run have no value, so do not fail */
- if (!ua->argv[i] && j != YES_POS /*yes*/) {
- ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
-- return true;
-+ return false;
- }
- Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
- switch (j) {
+++ /dev/null
-
- This patch resolves bug #908 where a tape is not properly mounted
- (recognized) during a poll.
-
- Apply to version 2.2.4 (and perhaps older 2.2.x versions) with
-
- cd <bacula-source>
- patch -p0 <2.2.4-poll-mount.patch
- ./configure (your options)
- make
- ...
- make install
-
-Index: src/stored/dev.c
-===================================================================
---- src/stored/dev.c (revision 5553)
-+++ src/stored/dev.c (working copy)
-@@ -1844,7 +1844,8 @@
-
- /* Clean up device packet so it can be reused */
- clear_opened();
-- state &= ~(ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF);
-+ state &= ~(ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF|
-+ ST_MOUNTED|ST_MEDIA|ST_SHORT|ST_FREESPACE_OK|ST_PART_SPOOLED);
- label_type = B_BACULA_LABEL;
- file = block_num = 0;
- file_size = 0;
+++ /dev/null
-
- This patch resolves bug #969 where the user can't change the
- replace option in the restore menu
-
- Apply to version 2.2.4 (and perhaps older 2.2.x versions) with
-
- cd <bacula-source>
- patch -p0 <2.2.4-replace.patch
- ./configure (your options)
- make
- ...
- make install
-
---- src/dird/ua_run.c (révision 5721)
-+++ src/dird/ua_run.c (copie de travail)
-@@ -424,6 +424,7 @@
- }
- opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
- if (opt >= 0) {
-+ rc.replace = ReplaceOptions[opt].name;
- jcr->replace = ReplaceOptions[opt].token;
- }
- goto try_again;
-
+++ /dev/null
-
- This patch resolves bug #955 where the director segfault when
- where= option isn't specified anywhere.
-
- Apply to version 2.2.4 (and perhaps older 2.2.x versions) with
-
- cd <bacula-source>
- patch -p0 <2.2.4-restore.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-Index: src/dird/restore.c
-===================================================================
---- src/dird/restore.c (revision 5601)
-+++ src/dird/restore.c (working copy)
-@@ -173,7 +173,7 @@
- }
-
- /* Send restore command */
-- char replace, *where, *cmd=NULL;
-+ char replace, *where, *cmd;
- char empty = '\0';
-
- if (jcr->replace != 0) {
-@@ -183,8 +183,6 @@
- } else {
- replace = REPLACE_ALWAYS; /* always replace */
- }
--
-- where = ∅ /* default */
-
- if (jcr->RegexWhere) {
- where = jcr->RegexWhere; /* override */
-@@ -199,7 +197,11 @@
- } else if (jcr->job->RestoreWhere) {
- where = jcr->job->RestoreWhere; /* no override take from job */
- cmd = restorecmd;
-- }
-+
-+ } else { /* nothing was specified */
-+ where = ∅ /* use default */
-+ cmd = restorecmd;
-+ }
-
- jcr->prefix_links = jcr->job->PrefixLinks;
-
+++ /dev/null
-
- This patch applies to Bacula version 2.2.4 (possibly earlier 2.2.x versions)
- and fixes a Storage daemon authentication problem with the FD. This fixes
- bug #953. The patch also adds a bit of additional debug code and significantly
- strengthens the SD session key.
-
- Apply it to 2.2.4 with:
-
- cd <bacula-source>
- patch -p0 <2.2.4-sd-auth-fail.patch
- make
- ...
- make install
-
-
-Index: src/stored/job.c
-===================================================================
---- src/stored/job.c (revision 5602)
-+++ src/stored/job.c (working copy)
-@@ -73,6 +73,7 @@
- {
- int JobId;
- char auth_key[100];
-+ char seed[100];
- BSOCK *dir = jcr->dir_bsock;
- POOL_MEM job_name, client_name, job, fileset_name, fileset_md5;
- int JobType, level, spool_attributes, no_attributes, spool_data;
-@@ -91,7 +92,7 @@
- &write_part_after_job, &PreferMountedVols);
- if (stat != 13) {
- pm_strcpy(jcr->errmsg, dir->msg);
-- bnet_fsend(dir, BAD_job, stat, jcr->errmsg);
-+ dir->fsend(BAD_job, stat, jcr->errmsg);
- Dmsg1(100, ">dird: %s", dir->msg);
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- return false;
-@@ -134,9 +135,10 @@
- /*
- * Pass back an authorization key for the File daemon
- */
-- make_session_key(auth_key, NULL, 1);
-- bnet_fsend(dir, OKjob, jcr->VolSessionId, jcr->VolSessionTime, auth_key);
-- Dmsg1(100, ">dird: %s", dir->msg);
-+ bsnprintf(seed, sizeof(seed), "%p%d", jcr, JobId);
-+ make_session_key(auth_key, seed, 1);
-+ dir->fsend(OKjob, jcr->VolSessionId, jcr->VolSessionTime, auth_key);
-+ Dmsg2(100, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg);
- jcr->sd_auth_key = bstrdup(auth_key);
- memset(auth_key, 0, sizeof(auth_key));
- generate_daemon_event(jcr, "JobStart");
-@@ -169,17 +171,18 @@
- timeout.tv_nsec = tv.tv_usec * 1000;
- timeout.tv_sec = tv.tv_sec + me->client_wait;
-
-- Dmsg2(100, "%s waiting %d sec for FD to contact SD\n",
-- jcr->Job, (int)me->client_wait);
-+ Dmsg3(050, "%s waiting %d sec for FD to contact SD key=%s\n",
-+ jcr->Job, (int)me->client_wait, jcr->sd_auth_key);
-+
- /*
- * Wait for the File daemon to contact us to start the Job,
- * when he does, we will be released, unless the 30 minutes
- * expires.
- */
- P(mutex);
-- for ( ; !job_canceled(jcr); ) {
-+ while ( !jcr->authenticated && !job_canceled(jcr) ) {
- errstat = pthread_cond_timedwait(&jcr->job_start_wait, &mutex, &timeout);
-- if (errstat == 0 || errstat == ETIMEDOUT) {
-+ if (errstat == ETIMEDOUT || errstat == EINVAL || errstat == EPERM) {
- break;
- }
- }
-@@ -195,7 +198,7 @@
- }
-
- /*
-- * After receiving a connection (in job.c) if it is
-+ * After receiving a connection (in dircmd.c) if it is
- * from the File daemon, this routine is called.
- */
- void handle_filed_connection(BSOCK *fd, char *job_name)
-@@ -204,8 +207,8 @@
-
- bmicrosleep(0, 50000); /* wait 50 millisecs */
- if (!(jcr=get_jcr_by_full_name(job_name))) {
-- Jmsg1(NULL, M_FATAL, 0, _("Job name not found: %s\n"), job_name);
-- Dmsg1(100, "Job name not found: %s\n", job_name);
-+ Jmsg1(NULL, M_FATAL, 0, _("FD connect failed: Job name not found: %s\n"), job_name);
-+ Dmsg1(3, "**** Job \"%s\" not found", job_name);
- return;
- }
-
-@@ -216,7 +219,7 @@
-
- if (jcr->authenticated) {
- Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"),
-- jcr->JobId, jcr->Job);
-+ (uint32_t)jcr->JobId, jcr->Job);
- free_jcr(jcr);
- return;
- }
-@@ -229,7 +232,7 @@
- Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n"));
- } else {
- jcr->authenticated = true;
-- Dmsg1(110, "OK Authentication Job %s\n", jcr->Job);
-+ Dmsg2(110, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job);
- }
-
- if (!jcr->authenticated) {
-@@ -274,9 +277,9 @@
- }
- ok = dir_update_device(jcr, device->dev);
- if (ok) {
-- ok = bnet_fsend(dir, OK_query);
-+ ok = dir->fsend(OK_query);
- } else {
-- bnet_fsend(dir, NO_query);
-+ dir->fsend(NO_query);
- }
- return ok;
- }
-@@ -289,9 +292,9 @@
- }
- ok = dir_update_changer(jcr, changer);
- if (ok) {
-- ok = bnet_fsend(dir, OK_query);
-+ ok = dir->fsend(OK_query);
- } else {
-- bnet_fsend(dir, NO_query);
-+ dir->fsend(NO_query);
- }
- return ok;
- }
-@@ -299,12 +302,12 @@
- /* If we get here, the device/autochanger was not found */
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
-- bnet_fsend(dir, NO_device, dev_name.c_str());
-+ dir->fsend(NO_device, dev_name.c_str());
- Dmsg1(100, ">dird: %s\n", dir->msg);
- } else {
- unbash_spaces(dir->msg);
- pm_strcpy(jcr->errmsg, dir->msg);
-- bnet_fsend(dir, BAD_query, jcr->errmsg);
-+ dir->fsend(BAD_query, jcr->errmsg);
- Dmsg1(100, ">dird: %s\n", dir->msg);
- }
-
-@@ -322,7 +325,7 @@
- {
- Dmsg1(900, "stored_free_jcr JobId=%u\n", jcr->JobId);
- if (jcr->file_bsock) {
-- bnet_close(jcr->file_bsock);
-+ jcr->file_bsock->close();
- jcr->file_bsock = NULL;
- }
- if (jcr->job_name) {
+++ /dev/null
-
- This patch fixes several problems: it fixes incorrect or incomplete error
- messages; it fixes a problem opening the SQLite3 database when multiple
- simultaneous jobs were running; it fixes a bug with certain versions of
- MySQL where batch inserts failed because of table name character case
- (upper/lower) differences.
-
- It can be applied to version 2.2.4 (and possibly earlier 2.2.x versions)
- with:
-
- cd <bacula-source>
- patch -p0 <2.2.4-sql.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-
-Index: src/cats/sql.c
-===================================================================
---- src/cats/sql.c (revision 5687)
-+++ src/cats/sql.c (working copy)
-@@ -115,7 +115,6 @@
-
- bacula_db_version = 0;
- if (!db_sql_query(mdb, query, int_handler, (void *)&bacula_db_version)) {
-- Mmsg(mdb->errmsg, "Database not created or server not running.\n");
- Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
- return false;
- }
-Index: src/cats/sqlite.c
-===================================================================
---- src/cats/sqlite.c (revision 5687)
-+++ src/cats/sqlite.c (working copy)
-@@ -148,6 +148,7 @@
- int len;
- struct stat statbuf;
- int errstat;
-+ int retry = 0;
-
- P(mutex);
- if (mdb->connected) {
-@@ -157,8 +158,9 @@
- mdb->connected = FALSE;
-
- if ((errstat=rwl_init(&mdb->lock)) != 0) {
-+ berrno be;
- Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
-- strerror(errstat));
-+ be.bstrerror(errstat));
- V(mutex);
- return 0;
- }
-@@ -178,28 +180,28 @@
- return 0;
- }
-
-+ for (mdb->db=NULL; !mdb->db && retry++ < 10; ) {
- #ifdef HAVE_SQLITE3
-- int stat = sqlite3_open(db_name, &mdb->db);
-- if (stat != SQLITE_OK) {
-- mdb->sqlite_errmsg = (char *)sqlite3_errmsg(mdb->db);
-- sqlite3_close(mdb->db);
-- mdb->db = NULL;
-- } else {
-- mdb->sqlite_errmsg = NULL;
-- }
--#ifdef SQLITE3_INIT_QUERY
-- db_sql_query(mdb, SQLITE3_INIT_QUERY, NULL, NULL);
--#endif
--
-+ int stat = sqlite3_open(db_name, &mdb->db);
-+ if (stat != SQLITE_OK) {
-+ mdb->sqlite_errmsg = (char *)sqlite3_errmsg(mdb->db);
-+ sqlite3_close(mdb->db);
-+ mdb->db = NULL;
-+ } else {
-+ mdb->sqlite_errmsg = NULL;
-+ }
- #else
-- mdb->db = sqlite_open(
-- db_name, /* database name */
-- 644, /* mode */
-- &mdb->sqlite_errmsg); /* error message */
-+ mdb->db = sqlite_open(
-+ db_name, /* database name */
-+ 644, /* mode */
-+ &mdb->sqlite_errmsg); /* error message */
- #endif
-
-- Dmsg0(300, "sqlite_open\n");
--
-+ Dmsg0(300, "sqlite_open\n");
-+ if (!mdb->db) {
-+ bmicrosleep(1, 0);
-+ }
-+ }
- if (mdb->db == NULL) {
- Mmsg2(&mdb->errmsg, _("Unable to open Database=%s. ERR=%s\n"),
- db_name, mdb->sqlite_errmsg ? mdb->sqlite_errmsg : _("unknown"));
-@@ -209,10 +211,6 @@
- }
- mdb->connected = true;
- free(db_name);
-- if (!check_tables_version(jcr, mdb)) {
-- V(mutex);
-- return 0;
-- }
-
- /* set busy handler to wait when we use mult_db_connections = 1 */
- #ifdef HAVE_SQLITE3
-@@ -221,6 +219,16 @@
- sqlite_busy_handler(mdb->db, my_busy_handler, NULL);
- #endif
-
-+#if defined(HAVE_SQLITE3) && defined(SQLITE3_INIT_QUERY)
-+ db_sql_query(mdb, SQLITE3_INIT_QUERY, NULL, NULL);
-+#endif
-+
-+ if (!check_tables_version(jcr, mdb)) {
-+ V(mutex);
-+ return 0;
-+ }
-+
-+
- V(mutex);
- return 1;
- }
-@@ -448,16 +456,20 @@
- return mdb->fields[mdb->field++];
- }
-
--char *my_sqlite_batch_lock_query = "BEGIN";
--char *my_sqlite_batch_unlock_query = "COMMIT";
--char *my_sqlite_batch_fill_path_query = "INSERT INTO Path (Path) "
-- " SELECT DISTINCT Path FROM batch "
-- " EXCEPT SELECT Path FROM Path ";
-+#ifdef HAVE_BATCH_FILE_INSERT
-+const char *my_sqlite_batch_lock_query = "BEGIN";
-+const char *my_sqlite_batch_unlock_query = "COMMIT";
-
--char *my_sqlite_batch_fill_filename_query = "INSERT INTO Filename (Name) "
-- " SELECT DISTINCT Name FROM batch "
-- " EXCEPT SELECT Name FROM Filename ";
-+const char *my_sqlite_batch_fill_path_query =
-+ "INSERT INTO Path (Path)"
-+ " SELECT DISTINCT Path FROM batch"
-+ " EXCEPT SELECT Path FROM Path";
-
-+const char *my_sqlite_batch_fill_filename_query =
-+ "INSERT INTO Filename (Name)"
-+ " SELECT DISTINCT Name FROM batch "
-+ " EXCEPT SELECT Name FROM Filename";
-+#endif /* HAVE_BATCH_FILE_INSERT */
-
-
- #endif /* HAVE_SQLITE */
-Index: src/cats/cats.h
-===================================================================
---- src/cats/cats.h (revision 5687)
-+++ src/cats/cats.h (working copy)
-@@ -187,10 +187,10 @@
- int my_sqlite_query(B_DB *mdb, const char *cmd);
- void my_sqlite_field_seek(B_DB *mdb, int field);
- SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb);
--extern char* my_sqlite_batch_lock_query;
--extern char* my_sqlite_batch_unlock_query;
--extern char* my_sqlite_batch_fill_filename_query;
--extern char* my_sqlite_batch_fill_path_query;
-+extern const char* my_sqlite_batch_lock_query;
-+extern const char* my_sqlite_batch_unlock_query;
-+extern const char* my_sqlite_batch_fill_filename_query;
-+extern const char* my_sqlite_batch_fill_path_query;
-
-
- #else
-@@ -317,10 +317,10 @@
- int my_sqlite_query(B_DB *mdb, const char *cmd);
- void my_sqlite_field_seek(B_DB *mdb, int field);
- SQL_FIELD *my_sqlite_fetch_field(B_DB *mdb);
--extern char* my_sqlite_batch_lock_query;
--extern char* my_sqlite_batch_unlock_query;
--extern char* my_sqlite_batch_fill_filename_query;
--extern char* my_sqlite_batch_fill_path_query;
-+extern const char* my_sqlite_batch_lock_query;
-+extern const char* my_sqlite_batch_unlock_query;
-+extern const char* my_sqlite_batch_fill_filename_query;
-+extern const char* my_sqlite_batch_fill_path_query;
-
-
- #else
-@@ -398,11 +398,11 @@
- #define sql_batch_fill_path_query my_mysql_batch_fill_path_query
-
-
--extern char* my_mysql_batch_lock_path_query;
--extern char* my_mysql_batch_lock_filename_query;
--extern char* my_mysql_batch_unlock_tables_query;
--extern char* my_mysql_batch_fill_filename_query;
--extern char* my_mysql_batch_fill_path_query;
-+extern const char* my_mysql_batch_lock_path_query;
-+extern const char* my_mysql_batch_lock_filename_query;
-+extern const char* my_mysql_batch_unlock_tables_query;
-+extern const char* my_mysql_batch_fill_filename_query;
-+extern const char* my_mysql_batch_fill_path_query;
- extern void my_mysql_free_result(B_DB *mdb);
-
- #else
-@@ -486,11 +486,11 @@
- int my_postgresql_batch_insert(JCR *jcr, B_DB *mdb, ATTR_DBR *ar);
- char *my_postgresql_copy_escape(char *dest, char *src, size_t len);
-
--extern char* my_pg_batch_lock_path_query;
--extern char* my_pg_batch_lock_filename_query;
--extern char* my_pg_batch_unlock_tables_query;
--extern char* my_pg_batch_fill_filename_query;
--extern char* my_pg_batch_fill_path_query;
-+extern const char* my_pg_batch_lock_path_query;
-+extern const char* my_pg_batch_lock_filename_query;
-+extern const char* my_pg_batch_unlock_tables_query;
-+extern const char* my_pg_batch_fill_filename_query;
-+extern const char* my_pg_batch_fill_path_query;
-
- /* "Generic" names for easier conversion */
- #define sql_store_result(x) ((x)->result)
-Index: src/cats/mysql.c
-===================================================================
---- src/cats/mysql.c (revision 5687)
-+++ src/cats/mysql.c (working copy)
-@@ -149,8 +149,9 @@
- }
-
- if ((errstat=rwl_init(&mdb->lock)) != 0) {
-+ berrno be;
- Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
-- strerror(errstat));
-+ be.bstrerror(errstat));
- V(mutex);
- return 0;
- }
-@@ -403,33 +404,27 @@
- db_unlock(mdb);
- }
-
--char *my_mysql_batch_lock_path_query = "LOCK TABLES Path write, "
-- " batch write, "
-- " Path as p write ";
-+#ifdef HAVE_BATCH_FILE_INSERT
-+const char *my_mysql_batch_lock_path_query =
-+ "LOCK TABLES Path write, batch write, Path as p write";
-
-
--char *my_mysql_batch_lock_filename_query = "LOCK TABLES Filename write, "
-- " batch write, "
-- " Filename as f write ";
-+const char *my_mysql_batch_lock_filename_query =
-+ "LOCK TABLES Filename write, batch write, Filename as f write";
-
--char *my_mysql_batch_unlock_tables_query = "UNLOCK TABLES";
-+const char *my_mysql_batch_unlock_tables_query = "UNLOCK TABLES";
-
--char *my_mysql_batch_fill_path_query = "INSERT INTO Path (Path) "
-- " SELECT a.Path FROM "
-- " (SELECT DISTINCT Path "
-- " FROM batch) AS a "
-- " WHERE NOT EXISTS "
-- " (SELECT Path "
-- " FROM Path AS p "
-- " WHERE p.Path = a.Path) ";
-+const char *my_mysql_batch_fill_path_query =
-+ "INSERT INTO Path (Path) "
-+ "SELECT a.Path FROM "
-+ "(SELECT DISTINCT Path FROM batch) AS a WHERE NOT EXISTS "
-+ "(SELECT Path FROM Path AS p WHERE p.Path = a.Path)";
-
--char *my_mysql_batch_fill_filename_query = "INSERT INTO Filename (Name) "
-- " SELECT a.Name FROM "
-- " (SELECT DISTINCT Name "
-- " FROM batch) AS a "
-- " WHERE NOT EXISTS "
-- " (SELECT Name "
-- " FROM Filename AS f "
-- " WHERE f.Name = a.Name) ";
-+const char *my_mysql_batch_fill_filename_query =
-+ "INSERT INTO Filename (Name) "
-+ "SELECT a.Name FROM "
-+ "(SELECT DISTINCT Name FROM batch) AS a WHERE NOT EXISTS "
-+ "(SELECT Name FROM Filename AS f WHERE f.Name = a.Name)";
-+#endif /* HAVE_BATCH_FILE_INSERT */
-
- #endif /* HAVE_MYSQL */
-Index: src/cats/sql_create.c
-===================================================================
---- src/cats/sql_create.c (revision 5687)
-+++ src/cats/sql_create.c (working copy)
-@@ -668,6 +668,8 @@
- * };
- */
-
-+#ifdef HAVE_BATCH_FILE_INSERT
-+
- /* All sql_batch_* functions are used to do bulk batch insert in File/Filename/Path
- * tables. This code can be activated by adding "#define HAVE_BATCH_FILE_INSERT 1"
- * in baconfig.h
-@@ -690,13 +692,13 @@
-
- db_lock(mdb);
- ok = db_sql_query(mdb,
-- " CREATE TEMPORARY TABLE batch "
-- " (fileindex integer, "
-- " jobid integer, "
-- " path blob, "
-- " name blob, "
-- " lstat tinyblob, "
-- " md5 tinyblob) ",NULL, NULL);
-+ "CREATE TEMPORARY TABLE batch ("
-+ "FileIndex integer,"
-+ "JobId integer,"
-+ "Path blob,"
-+ "Name blob,"
-+ "LStat tinyblob,"
-+ "MD5 tinyblob)",NULL, NULL);
- db_unlock(mdb);
- return ok;
- }
-@@ -746,7 +748,6 @@
- return true;
- }
-
--#ifdef HAVE_BATCH_FILE_INSERT
- /*
- * Returns 1 if OK
- * 0 if failed
-@@ -794,7 +795,7 @@
-
- if (!db_sql_query(jcr->db_batch,sql_batch_fill_filename_query, NULL,NULL)) {
- Jmsg(jcr,M_FATAL,0,"Can't fill Filename table %s\n",jcr->db_batch->errmsg);
-- QUERY_DB(jcr, jcr->db_batch, sql_batch_unlock_tables_query);
-+ db_sql_query(jcr->db_batch, sql_batch_unlock_tables_query, NULL, NULL);
- return false;
- }
-
-@@ -804,12 +805,12 @@
- }
-
- if (!db_sql_query(jcr->db_batch,
-- " INSERT INTO File (FileIndex, JobId, PathId, FilenameId, LStat, MD5)"
-- " SELECT batch.FileIndex, batch.JobId, Path.PathId, "
-- " Filename.FilenameId,batch.LStat, batch.MD5 "
-- " FROM batch "
-- " JOIN Path ON (batch.Path = Path.Path) "
-- " JOIN Filename ON (batch.Name = Filename.Name) ",
-+ "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, LStat, MD5)"
-+ "SELECT batch.FileIndex, batch.JobId, Path.PathId, "
-+ "Filename.FilenameId,batch.LStat, batch.MD5 "
-+ "FROM batch "
-+ "JOIN Path ON (batch.Path = Path.Path) "
-+ "JOIN Filename ON (batch.Name = Filename.Name)",
- NULL,NULL))
- {
- Jmsg(jcr, M_FATAL, 0, "Can't fill File table %s\n", jcr->db_batch->errmsg);
-@@ -845,19 +846,24 @@
- mdb->db_port,
- mdb->db_socket,
- 1 /* multi_db = true */);
-+ if (!jcr->db_batch) {
-+ Mmsg1(&mdb->errmsg, _("Could not init batch database: \"%s\".\n"),
-+ jcr->db->db_name);
-+ Jmsg1(jcr, M_FATAL, 0, "%s", mdb->errmsg);
-+ return false;
-+ }
-
-- if (!jcr->db_batch || !db_open_database(jcr, jcr->db_batch)) {
-- Jmsg(jcr, M_FATAL, 0, _("Could not open database \"%s\".\n"),
-- jcr->db->db_name);
-- if (jcr->db_batch) {
-- Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db_batch));
-- }
-+ if (!db_open_database(jcr, jcr->db_batch)) {
-+ Mmsg2(&mdb->errmsg, _("Could not open database \"%s\": ERR=%s\n"),
-+ jcr->db->db_name, db_strerror(jcr->db_batch));
-+ Jmsg1(jcr, M_FATAL, 0, "%s", mdb->errmsg);
- return false;
- }
-
- if (!sql_batch_start(jcr, jcr->db_batch)) {
-- Jmsg(jcr, M_FATAL, 0,
-- "Can't start batch mode %s", db_strerror(jcr->db_batch));
-+ Mmsg1(&mdb->errmsg,
-+ "Can't start batch mode: ERR=%s", db_strerror(jcr->db_batch));
-+ Jmsg1(jcr, M_FATAL, 0, "%s", mdb->errmsg);
- return false;
- }
- Dmsg3(100, "initdb ref=%d connected=%d db=%p\n", jcr->db_batch->ref_count,
-@@ -870,10 +876,10 @@
- */
- if (!(ar->Stream == STREAM_UNIX_ATTRIBUTES ||
- ar->Stream == STREAM_UNIX_ATTRIBUTES_EX)) {
-- Mmsg1(&bdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
-+ Mmsg1(&mdb->errmsg, _("Attempt to put non-attributes into catalog. Stream=%d\n"),
- ar->Stream);
-- Jmsg(jcr, M_ERROR, 0, "%s", bdb->errmsg);
-- return 0;
-+ Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
-+ return false;
- }
-
- split_path_and_file(jcr, bdb, ar->fname);
-Index: src/cats/postgresql.c
-===================================================================
---- src/cats/postgresql.c (revision 5687)
-+++ src/cats/postgresql.c (working copy)
-@@ -605,13 +605,13 @@
- Dmsg0(500, "my_postgresql_batch_start started\n");
-
- if (my_postgresql_query(mdb,
-- " CREATE TEMPORARY TABLE batch "
-- " (fileindex int, "
-- " jobid int, "
-- " path varchar, "
-- " name varchar, "
-- " lstat varchar, "
-- " md5 varchar)") == 1)
-+ "CREATE TEMPORARY TABLE batch ("
-+ "fileindex int,"
-+ "jobid int,"
-+ "path varchar,"
-+ "name varchar,"
-+ "lstat varchar,"
-+ "md5 varchar)") == 1)
- {
- Dmsg0(500, "my_postgresql_batch_start failed\n");
- return 1;
-@@ -785,22 +785,29 @@
- return dest;
- }
-
--char *my_pg_batch_lock_path_query = "BEGIN; LOCK TABLE Path IN SHARE ROW EXCLUSIVE MODE";
-+#ifdef HAVE_BATCH_FILE_INSERT
-+const char *my_pg_batch_lock_path_query =
-+ "BEGIN; LOCK TABLE Path IN SHARE ROW EXCLUSIVE MODE";
-
-
--char *my_pg_batch_lock_filename_query = "BEGIN; LOCK TABLE Filename IN SHARE ROW EXCLUSIVE MODE";
-+const char *my_pg_batch_lock_filename_query =
-+ "BEGIN; LOCK TABLE Filename IN SHARE ROW EXCLUSIVE MODE";
-
--char *my_pg_batch_unlock_tables_query = "COMMIT";
-+const char *my_pg_batch_unlock_tables_query = "COMMIT";
-
--char *my_pg_batch_fill_path_query = "INSERT INTO Path (Path) "
-- " SELECT a.Path FROM "
-- " (SELECT DISTINCT Path FROM batch) AS a "
-- " WHERE NOT EXISTS (SELECT Path FROM Path WHERE Path = a.Path) ";
-+const char *my_pg_batch_fill_path_query =
-+ "INSERT INTO Path (Path) "
-+ "SELECT a.Path FROM "
-+ "(SELECT DISTINCT Path FROM batch) AS a "
-+ "WHERE NOT EXISTS (SELECT Path FROM Path WHERE Path = a.Path) ";
-
-
--char *my_pg_batch_fill_filename_query = "INSERT INTO Filename (Name) "
-- " SELECT a.Name FROM "
-- " (SELECT DISTINCT Name FROM batch) as a "
-- " WHERE NOT EXISTS "
-- " (SELECT Name FROM Filename WHERE Name = a.Name)";
-+const char *my_pg_batch_fill_filename_query =
-+ "INSERT INTO Filename (Name) "
-+ "SELECT a.Name FROM "
-+ "(SELECT DISTINCT Name FROM batch) as a "
-+ "WHERE NOT EXISTS "
-+ "(SELECT Name FROM Filename WHERE Name = a.Name)";
-+#endif /* HAVE_BATCH_FILE_INSERT */
-+
- #endif /* HAVE_POSTGRESQL */
+++ /dev/null
- This patch fixes bug #958 A Verify catalog Job that has differences reports Verify OK.
-
- Apply it to version 2.2.4 (possibly earlier versions with):
-
- cd <bacula-source>
- patch -p0 <2.2.4-verify.patch
- ./configure (your options)
- make
- ...
- make install
-
-Index: src/dird/verify.c
-===================================================================
---- src/dird/verify.c (revision 5553)
-+++ src/dird/verify.c (working copy)
-@@ -332,13 +332,10 @@
- }
-
- stat = wait_for_job_termination(jcr);
-- if (stat == JS_Terminated) {
-- verify_cleanup(jcr, stat);
-- return true;
-- }
-+ verify_cleanup(jcr, stat);
-+ return true;
-
- bail_out:
-- verify_cleanup(jcr, JS_ErrorTerminated);
- return false;
- }
-
-@@ -421,7 +418,7 @@
- jobstatus_to_ascii(jcr->FDJobStatus, fd_term_msg, sizeof(fd_term_msg));
- if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) {
- jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
-- Jmsg(jcr, msg_type, 0, _("Bacula %s %s (%s): %s\n"
-+ Jmsg(jcr, msg_type, 0, _("Bacula %s %s (%s): %s\n"
- " Build OS: %s %s %s\n"
- " JobId: %d\n"
- " Job: %s\n"
-@@ -456,7 +453,7 @@
- sd_term_msg,
- term_msg);
- } else {
-- Jmsg(jcr, msg_type, 0, _("Bacula %s %s (%s): %s\n"
-+ Jmsg(jcr, msg_type, 0, _("Bacula %s %s (%s): %s\n"
- " Build: %s %s %s\n"
- " JobId: %d\n"
- " Job: %s\n"
-@@ -750,7 +747,9 @@
- stat = JS_Differences;
- }
- free_pool_memory(fname);
-- set_jcr_job_status(jcr, stat);
-+ if (!job_canceled(jcr)) {
-+ jcr->JobStatus = stat;
-+ }
- return stat == JS_Terminated;
- }
-
-Index: src/lib/jcr.c
-===================================================================
---- src/lib/jcr.c (revision 5553)
-+++ src/lib/jcr.c (working copy)
-@@ -614,9 +614,8 @@
- /* Override more minor status */
- jcr->JobStatus = JobStatus;
- break;
-- default:
-- break;
- }
-+ break;
- default:
- jcr->JobStatus = JobStatus;
- }
+++ /dev/null
-
- This patch fixes the default behavior of a non-DEVELOPER version of Bacula
- to close STDIN, STDOUT, and STDERR so that an ssh that starts bacula
- will not hang. It also fixes a crash in bat when bat is executed and
- cannot connect to the Director (e.g. it is not running).
- This patch fixes bugs #991 and #993.
-
- Apply this fix to Bacula version 2.2.5 with:
-
- cd <bacula-source>
- patch -p0 <2.2.5-daemon.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-Index: src/lib/message.c
-===================================================================
---- src/lib/message.c (revision 5744)
-+++ src/lib/message.c (working copy)
-@@ -52,7 +52,8 @@
- */
- const char *working_directory = NULL; /* working directory path stored here */
- int verbose = 0; /* increase User messages */
--int debug_level = 1; /* debug level */
-+/* Keep debug level set to zero by default */
-+int debug_level = 0; /* debug level */
- time_t daemon_start_time = 0; /* Daemon start time */
- const char *version = VERSION " (" BDATE ")";
- char my_name[30]; /* daemon name is stored here */
-@@ -1338,7 +1339,7 @@
- jcr = get_jcr_from_tsd();
- }
- /* If no jcr or dequeuing send to daemon to avoid recursion */
-- if (!jcr || jcr->dequeuing) {
-+ if ((jcr && !jcr->msg_queue) || !jcr || jcr->dequeuing) {
- /* jcr==NULL => daemon message, safe to send now */
- Jmsg(jcr, item->type, item->mtime, "%s", item->msg);
- free(item);
+++ /dev/null
-
- This patch fixes bug #947 where a large number of emails were generated
- because the heartbeat interval was small and the tape in the drive did
- not correspond to the one wanted by Bacula.
-
- Apply the patch to version 2.2.5 (and probably any 2.2.x version) with:
-
- cd <bacula-source>
- ./configure <your options>
- patch -p0 <2.2.5-hb.patch
- make
- ...
- make install
-
-
-Index: src/stored/wait.c
-===================================================================
---- src/stored/wait.c (revision 5814)
-+++ src/stored/wait.c (working copy)
-@@ -40,9 +40,8 @@
- #include "bacula.h" /* pull in global headers */
- #include "stored.h" /* pull in Storage Deamon headers */
-
--//static bool double_jcr_wait_time(JCR *jcr);
-+const int dbglvl = 400;
-
--
- /*
- * Wait for SysOp to mount a tape on a specific device
- *
-@@ -62,7 +61,7 @@
- JCR *jcr = dcr->jcr;
-
- dev->dlock();
-- Dmsg1(100, "Enter blocked=%s\n", dev->print_blocked());
-+ Dmsg1(dbglvl, "Enter blocked=%s\n", dev->print_blocked());
- unmounted = is_device_unmounted(dev);
-
- dev->poll = false;
-@@ -84,27 +83,28 @@
- }
-
- if (!unmounted) {
-- Dmsg1(400, "blocked=%s\n", dev->print_blocked());
-+ Dmsg1(dbglvl, "blocked=%s\n", dev->print_blocked());
- dev->dev_prev_blocked = dev->blocked();
- dev->set_blocked(BST_WAITING_FOR_SYSOP); /* indicate waiting for mount */
- }
-
- for ( ; !job_canceled(jcr); ) {
-- time_t now, start;
-+ time_t now, start, total_waited;
-
- gettimeofday(&tv, &tz);
- timeout.tv_nsec = tv.tv_usec * 1000;
- timeout.tv_sec = tv.tv_sec + add_wait;
-
-- Dmsg4(400, "I'm going to sleep on device %s. HB=%d wait=%d add_wait=%d\n",
-- dev->print_name(), (int)me->heartbeat_interval, dev->wait_sec, add_wait);
-+ Dmsg4(dbglvl, "I'm going to sleep on device %s. HB=%d rem_wait=%d add_wait=%d\n",
-+ dev->print_name(), (int)me->heartbeat_interval, dev->rem_wait_sec, add_wait);
- start = time(NULL);
- /* Wait required time */
- stat = pthread_cond_timedwait(&dev->wait_next_vol, &dev->m_mutex, &timeout);
-- Dmsg2(400, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
-+ Dmsg2(dbglvl, "Wokeup from sleep on device stat=%d blocked=%s\n", stat,
- dev->print_blocked());
-
- now = time(NULL);
-+ total_waited = now - first_start;
- dev->rem_wait_sec -= (now - start);
-
- /* Note, this always triggers the first time. We want that. */
-@@ -113,7 +113,7 @@
- /* send heartbeats */
- if (jcr->file_bsock) {
- jcr->file_bsock->signal(BNET_HEARTBEAT);
-- Dmsg0(400, "Send heartbeat to FD.\n");
-+ Dmsg0(dbglvl, "Send heartbeat to FD.\n");
- }
- if (jcr->dir_bsock) {
- jcr->dir_bsock->signal(BNET_HEARTBEAT);
-@@ -131,7 +131,7 @@
-
-
- if (dev->rem_wait_sec <= 0) { /* on exceeding wait time return */
-- Dmsg0(400, "Exceed wait time.\n");
-+ Dmsg0(dbglvl, "Exceed wait time.\n");
- stat = W_TIMEOUT;
- break;
- }
-@@ -142,8 +142,8 @@
- unmounted = is_device_unmounted(dev);
-
- if (!unmounted && dev->vol_poll_interval &&
-- (now - first_start >= dev->vol_poll_interval)) {
-- Dmsg1(400, "In wait blocked=%s\n", dev->print_blocked());
-+ (total_waited >= dev->vol_poll_interval)) {
-+ Dmsg1(dbglvl, "poll return in wait blocked=%s\n", dev->print_blocked());
- dev->poll = true; /* returning a poll event */
- stat = W_POLL;
- break;
-@@ -152,6 +152,7 @@
- * Check if user mounted the device while we were waiting
- */
- if (dev->blocked() == BST_MOUNT) { /* mount request ? */
-+ Dmsg0(dbglvl, "Mounted return.\n");
- stat = W_MOUNT;
- break;
- }
-@@ -160,30 +161,39 @@
- * If we did not timeout, then some event happened, so
- * return to check if state changed.
- */
-- if (stat != 0) {
-+ if (stat != ETIMEDOUT) {
-+ berrno be;
-+ Dmsg2(dbglvl, "Wake return. stat=%d. ERR=%s\n", stat, be.bstrerror(stat));
- stat = W_WAKE; /* someone woke us */
- break;
- }
-
- /*
- * At this point, we know we woke up because of a timeout,
-- * that was due to a heartbeat, so we just update
-- * the wait counters and continue.
-+ * that was due to a heartbeat, because any other reason would
-+ * have caused us to return, so update the wait counters and continue.
- */
-- add_wait = dev->wait_sec - (now - start);
-+ add_wait = dev->rem_wait_sec;
-+ if (me->heartbeat_interval && add_wait > me->heartbeat_interval) {
-+ add_wait = me->heartbeat_interval;
-+ }
-+ /* If the user did not unmount the tape and we are polling, ensure
-+ * that we poll at the correct interval.
-+ */
-+ if (!unmounted && dev->vol_poll_interval &&
-+ add_wait > dev->vol_poll_interval - total_waited) {
-+ add_wait = dev->vol_poll_interval - total_waited;
-+ }
- if (add_wait < 0) {
- add_wait = 0;
- }
-- if (me->heartbeat_interval && add_wait > me->heartbeat_interval) {
-- add_wait = me->heartbeat_interval;
-- }
- }
-
- if (!unmounted) {
- dev->set_blocked(dev->dev_prev_blocked); /* restore entry state */
-- Dmsg1(400, "set %s\n", dev->print_blocked());
-+ Dmsg1(dbglvl, "set %s\n", dev->print_blocked());
- }
-- Dmsg1(400, "Exit blocked=%s\n", dev->print_blocked());
-+ Dmsg1(dbglvl, "Exit blocked=%s\n", dev->print_blocked());
- dev->dunlock();
- return stat;
- }
-@@ -209,7 +219,7 @@
- const int max_wait_time = 1 * 60; /* wait 1 minute */
- char ed1[50];
-
-- Dmsg0(100, "Enter wait_for_device\n");
-+ Dmsg0(dbglvl, "Enter wait_for_device\n");
- P(device_release_mutex);
-
- if (++retries % 5 == 0) {
-@@ -222,14 +232,14 @@
- timeout.tv_nsec = tv.tv_usec * 1000;
- timeout.tv_sec = tv.tv_sec + max_wait_time;
-
-- Dmsg1(100, "JobId=%u going to wait for a device.\n", (uint32_t)jcr->JobId);
-+ Dmsg0(dbglvl, "Going to wait for a device.\n");
-
- /* Wait required time */
- stat = pthread_cond_timedwait(&wait_device_release, &device_release_mutex, &timeout);
-- Dmsg2(100, "JobId=%u wokeup from sleep on device stat=%d\n", (uint32_t)jcr->JobId, stat);
-+ Dmsg1(dbglvl, "Wokeup from sleep on device stat=%d\n", stat);
-
- V(device_release_mutex);
-- Dmsg2(100, "JobId=%u return from wait_device ok=%d\n", (uint32_t)jcr->JobId, ok);
-+ Dmsg1(dbglvl, "Return from wait_device ok=%d\n", ok);
- return ok;
- }
-
+++ /dev/null
-
- This bug fixes the LastWritten field which was updated during
- a restore (or a reading migration)
- This fixes bug #982
-
- This patch applies to Bacula version 2.2.5 (and previous versions),
- and can be applied with the following:
-
- cd <bacula-source>
- patch -p0 <2.2.5-lastwritten.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-
-Index: src/dird/catreq.c
-===================================================================
---- src/dird/catreq.c (révision 5789)
-+++ src/dird/catreq.c (copie de travail)
-@@ -266,6 +266,11 @@
- }
- }
- Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
-+ /* Check if the volume has been written by the job,
-+ * and update the LastWritten field if needed */
-+ if (mr.VolBlocks != sdmr.VolBlocks) {
-+ mr.LastWritten = sdmr.LastWritten;
-+ }
- /* Copy updated values to original media record */
- mr.VolJobs = sdmr.VolJobs;
- mr.VolFiles = sdmr.VolFiles;
-@@ -274,7 +279,6 @@
- mr.VolMounts = sdmr.VolMounts;
- mr.VolErrors = sdmr.VolErrors;
- mr.VolWrites = sdmr.VolWrites;
-- mr.LastWritten = sdmr.LastWritten;
- mr.Slot = sdmr.Slot;
- mr.InChanger = sdmr.InChanger;
- mr.VolReadTime = sdmr.VolReadTime;
+++ /dev/null
-
- This bug fixes the warning message that prints each time an automatic
- Volume name is created. This fixes bug #979
-
- This patch applies to Bacula version 2.2.5 (not to previous versions),
- and can be applied with the following:
-
- cd <bacula-source>
- patch -p0 <2.2.5-newvol.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-
-Index: src/dird/newvol.c
-===================================================================
---- src/dird/newvol.c (revision 5717)
-+++ src/dird/newvol.c (working copy)
-@@ -124,7 +124,7 @@
- mr->VolumeName[0] = 0;
- bstrncpy(name, pr->LabelFormat, sizeof(name));
- ctx.value = 0;
-- Mmsg(query, "SELECT MAX(MediaId) FROM Media,POOL WHERE Pool.PoolId=%s",
-+ Mmsg(query, "SELECT MAX(MediaId) FROM Media,Pool WHERE Pool.PoolId=%s",
- edit_int64(pr->PoolId, ed1));
- if (!db_sql_query(jcr->db, query.c_str(), db_int64_handler, (void *)&ctx)) {
- Jmsg(jcr, M_WARNING, 0, _("SQL failed, but ignored. ERR=%s\n"), db_strerror(jcr->db));
+++ /dev/null
- After a sql error, the error message that is printed
- is incorrect and does not include the postgresql error message.
- It fixes #989
-
- This patch applies to Bacula version 2.2.5 (and previous versions),
- and can be applied with the following:
-
- cd <bacula-source>
- patch -p0 <2.2.5-postgresql-errors.patch
- ./configure (your options)
- make
- ...
- make install
-
-
-Index: src/cats/cats.h
-===================================================================
---- src/cats/cats.h (révision 5763)
-+++ src/cats/cats.h (copie de travail)
-@@ -498,7 +498,7 @@
- #define sql_fetch_row(x) my_postgresql_fetch_row(x)
- #define sql_query(x, y) my_postgresql_query((x), (y))
- #define sql_close(x) PQfinish((x)->db)
--#define sql_strerror(x) PQresultErrorMessage((x)->result)
-+#define sql_strerror(x) PQerrorMessage((x)->db)
- #define sql_num_rows(x) ((unsigned) PQntuples((x)->result))
- #define sql_data_seek(x, i) my_postgresql_data_seek((x), (i))
- #define sql_affected_rows(x) ((unsigned) atoi(PQcmdTuples((x)->result)))
+++ /dev/null
-
- This patch activates the Close button in the tray monitor window.
- It fixes bug #986.
-
- Apply it to Bacula version 2.2.5 with:
-
- cd <bacula-source>
- patch -p0 <2.2.5-tray-monitor.patch
- make
- ...
- make install
-
-Index: src/tray-monitor/tray-monitor.c
-===================================================================
---- src/tray-monitor/tray-monitor.c (revision 5717)
-+++ src/tray-monitor/tray-monitor.c (working copy)
-@@ -478,7 +478,7 @@
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0);
-
- button = new_image_button("gtk-close", _("Close"));
--// g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtk_widget_hide), G_OBJECT(window));
-+ g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtk_widget_hide), G_OBJECT(window));
- gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0);
-
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+++ /dev/null
-
- This patch fixes bug #1003 where putting the message output from
- a Verify job into the catalog results in a recursive loop. The problem
- seems to show up only with postgresql (to be verified).
-
- Apply it to version 2.2.5 (or probably any previous 2.2.x version) with
-
- cd <bacula-source>
- ./configure <your-options> not necessary if already configured
- patch -p0 <2.2.5-verify-loop.patch
- make
- ...
- make install
-
-
-Index: src/dird/verify.c
-===================================================================
---- src/dird/verify.c (revision 5814)
-+++ src/dird/verify.c (working copy)
-@@ -767,11 +767,11 @@
- return 1;
- }
- if (!jcr->fn_printed) {
-- Jmsg(jcr, M_INFO, 0, _("\nThe following files are in the Catalog but not on %s:\n"),
-+ Qmsg(jcr, M_INFO, 0, _("\nThe following files are in the Catalog but not on %s:\n"),
- jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG ? "the Volume(s)" : "disk");
- jcr->fn_printed = true;
- }
-- Jmsg(jcr, M_INFO, 0, " %s%s\n", row[0]?row[0]:"", row[1]?row[1]:"");
-+ Qmsg(jcr, M_INFO, 0, " %s%s\n", row[0]?row[0]:"", row[1]?row[1]:"");
- return 0;
- }
-
+++ /dev/null
-
- This patch fixes the infinite loop when trying to increase the
- maximum number of volumes in a Pool during the add command.
- This patch fixes bug #1008.
-
- It can be applied to Bacula version 2.2.6 (and probably earlier
- 2.2.x versions) with:
-
- cd <bacula-source>
- ./configure <your options>
- patch -p0 <2.2.6-add.patch
- make
- ...
- make install
-
-Index: src/dird/ua_cmds.c
-===================================================================
---- src/dird/ua_cmds.c (revision 5901)
-+++ src/dird/ua_cmds.c (working copy)
-@@ -244,12 +244,10 @@
-
- while (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) {
- ua->warning_msg(_("Pool already has maximum volumes=%d\n"), pr.MaxVols);
-- for (;;) {
-- if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
-- return 1;
-- }
-- pr.MaxVols = ua->pint32_val;
-+ if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
-+ return 1;
- }
-+ pr.MaxVols = ua->pint32_val;
- }
-
- /* Get media type */
+++ /dev/null
-
- This patch fixes bug #1015 where bacula failed to restore acl to a socket
- because Bacula no longer restores sockets.
-
- This fix will tell to bacula-fd to skip all socket file.
-
- Apply it to version 2.2.6 (or probably any previous 2.2.x version) with
-
- cd <bacula-source>
- ./configure <your-options> not necessary if already configured
- patch -p0 < 2.2.6-backup-restore-socket.patch
- make
- ...
- make install
-
-Index: src/filed/backup.c
-===================================================================
---- src/filed/backup.c (révision 5882)
-+++ src/filed/backup.c (copie de travail)
-@@ -279,6 +279,10 @@
- break;
- case FT_SPEC:
- Dmsg1(130, "FT_SPEC saving: %s\n", ff_pkt->fname);
-+ if (S_ISSOCK(ff_pkt->statp.st_mode)) {
-+ Jmsg(jcr, M_SKIPPED, 1, _(" Socket file skipped: %s\n"), ff_pkt->fname);
-+ return 1;
-+ }
- break;
- case FT_RAW:
- Dmsg1(130, "FT_RAW saving: %s\n", ff_pkt->fname);
+++ /dev/null
-
- This patch fixes bcopy so that it produces correct Volumes.
- It fixes bug #1022.
-
- Apply this patch to version 2.2.6 and possibly any 2.2.x version with:
-
- cd <bacula-source>
- patch -p0 2.2.6-bcopy.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/stored/bcopy.c
-===================================================================
---- src/stored/bcopy.c (revision 6010)
-+++ src/stored/bcopy.c (working copy)
-@@ -89,6 +89,7 @@
- char *iVolumeName = NULL;
- char *oVolumeName = NULL;
- bool ignore_label_errors = false;
-+ bool ok;
-
- setlocale(LC_ALL, "");
- bindtextdomain("bacula", LOCALEDIR);
-@@ -199,9 +200,11 @@
- }
- out_block = out_jcr->dcr->block;
-
-- read_records(in_jcr->dcr, record_cb, mount_next_read_volume);
-- if (!write_block_to_device(out_jcr->dcr)) {
-- Pmsg0(000, _("Write of last block failed.\n"));
-+ ok = read_records(in_jcr->dcr, record_cb, mount_next_read_volume);
-+ if (ok || out_dev->can_write()) {
-+ if (!write_block_to_device(out_jcr->dcr)) {
-+ Pmsg0(000, _("Write of last block failed.\n"));
-+ }
- }
-
- Pmsg2(000, _("%u Jobs copied. %u records copied.\n"), jobs, records);
-@@ -253,6 +256,7 @@
- out_dev->print_name(), out_dev->bstrerror());
- Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
- out_dev->bstrerror());
-+ return false;
- }
- }
- if (!write_block_to_device(out_jcr->dcr)) {
-@@ -260,8 +264,9 @@
- out_dev->print_name(), out_dev->bstrerror());
- Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
- out_dev->bstrerror());
-+ return false;
- }
-- break;
-+ return true;
- case EOM_LABEL:
- Pmsg0(000, _("EOM label not copied.\n"));
- return true;
-@@ -269,7 +274,7 @@
- Pmsg0(000, _("EOT label not copied.\n"));
- return true;
- default:
-- break;
-+ return true;
- }
- }
-
-@@ -283,7 +288,7 @@
- out_dev->print_name(), out_dev->bstrerror());
- Jmsg(out_jcr, M_FATAL, 0, _("Cannot fixup device error. %s\n"),
- out_dev->bstrerror());
-- break;
-+ return false;
- }
- }
- return true;
+++ /dev/null
- This patch should fix #1016 when there are more than one "part" to write.
- Instead of each part being stored on disk, written to DVD, then deleted from
- disk, all parts are written to disk, and only the last is written and deleted
- from disk.
-
- Apply it to 2.2.6 (and possibly previous 2.2.x versions) with:
-
- cd <bacula-source>
- patch -p0 <2.2.6-dvdwrite_trialfix.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/stored/dev.c
-===================================================================
---- src/stored/dev.c (revision 5996)
-+++ src/stored/dev.c (working copy)
-@@ -1856,7 +1856,7 @@
- /* Clean up device packet so it can be reused */
- clear_opened();
- state &= ~(ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF|
-- ST_MOUNTED|ST_MEDIA|ST_SHORT|ST_FREESPACE_OK|ST_PART_SPOOLED);
-+ ST_MOUNTED|ST_MEDIA|ST_SHORT);
- label_type = B_BACULA_LABEL;
- file = block_num = 0;
- file_size = 0;
+++ /dev/null
- This patch should fix the Mac OS X build problem on the latest
- Darwin, where sys/types.h was not included correctly (apparently
- due to a change in the Mac headers). The solution was to explicitly
- ensure that it is defined for the ./configure.
- This patch fixes bug #1020.
-
- This patch also has a rebuild of configure that includes the Debian
- qt4 kludge (look for alternate qt4 names).
-
- Apply it to 2.2.6 (and possibly previous 2.2.x versions) with:
-
- cd <bacula-source>
- patch -p0 <2.2.6-mac-build.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: configure
-===================================================================
---- configure (revision 5979)
-+++ configure (working copy)
-@@ -309,7 +309,7 @@
- # include <unistd.h>
- #endif"
-
--ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir archivedir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS BUILD_DIR TOP_DIR TRUEPRG FALSEPRG VERSION DATE LSMDATE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB MV RM CP SED ECHO CMP TBL AR OPENSSL MTX DD MKISOFS PYTHON GROWISOFS DVDRWMEDIAINFO DVDRWFORMAT PKGCONFIG WXCONFIG WXFLAGS CDRECORD PIDOF AWK ARFLAGS MAKE_SHELL LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os HAVE_SUN_OS_TRUE HAVE_SUN_OS_FALSE HAVE_OSF1_OS_TRUE HAVE_OSF1_OS_FALSE HAVE_AIX_OS_TRUE HAVE_AIX_OS_FALSE HAVE_HPUX_OS_TRUE HAVE_HPUX_OS_FALSE HAVE_LINUX_OS_TRUE HAVE_LINUX_OS_FALSE HAVE_FREEBSD_OS_TRUE HAVE_FREEBSD_OS_FALSE HAVE_NETBSD_OS_TRUE HAVE_NETBSD_OS_FALSE HAVE_OPENBSD_OS_TRUE HAVE_OPENBSD_OS_FALSE HAVE_BSDI_OS_TRUE HAVE_BSDI_OS_FALSE HAVE_SGI_OS_TRUE HAVE_SGI_OS_FALSE HAVE_IRIX_OS_TRUE HAVE_IRIX_OS_FALSE HAVE_DARWIN_OS_TRUE HAVE_DARWIN_OS_FALSE SET_MAKE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE INTL_MACOSX_LIBS LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB GLIBC2 ALLOCA GLIBC21 HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX GNOME_INCLUDEDIR GNOMEUI_LIBS GNOME_LIBDIR GNOME_LIBS GNOME_DIR BAT_DIR QWT_INC QWT_LDFLAGS WXCONS_CPPFLAGS WXCONS_LDFLAGS WX_DIR TRAY_MONITOR_CPPFLAGS TRAY_MONITOR_LDFLAGS TRAY_MONITOR_DIR TTOOL_LDFLAGS STATIC_FD STATIC_SD STATIC_DIR STATIC_CONS STATIC_GNOME_CONS STATIC_WX_CONS ALL_DIRS DIRD_DIR DIR_TOOLS STORED_DIR CONS_INC CONS_OBJ CONS_SRC CONS_LIBS CONS_LDFLAGS READLINE_SRC PYTHON_LIBS PYTHON_INCDIR OPENSSL_LIBS OPENSSL_INC working_dir scriptdir dump_email job_email smtp_host piddir subsysdir baseport dir_port fd_port sd_port dir_password fd_password sd_password mon_dir_password mon_fd_password mon_sd_password db_name db_user dir_user dir_group sd_user sd_group fd_user fd_group SBINPERM SQL_LFLAGS SQL_INCLUDE SQL_BINDIR cats DB_TYPE GETCONF ac_ct_GETCONF X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LIBOBJS FDLIBS DEBUG DINCLUDE DLIB DB_LIBS WCFLAGS WLDFLAGS WRAPLIBS OBJLIST hostname TAPEDRIVE PSCMD WIN32 MACOSX DISTNAME DISTVER LTLIBOBJS'
-+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS BUILD_DIR TOP_DIR TRUEPRG FALSEPRG VERSION DATE LSMDATE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CXX CXXFLAGS ac_ct_CXX CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB MV RM CP SED ECHO CMP TBL AR OPENSSL MTX DD MKISOFS PYTHON GROWISOFS DVDRWMEDIAINFO DVDRWFORMAT PKGCONFIG QMAKE QMAKEQT4 WXCONFIG WXFLAGS CDRECORD PIDOF AWK ARFLAGS MAKE_SHELL LOCAL_LIBS LOCAL_CFLAGS LOCAL_LDFLAGS LOCAL_DEFS build build_cpu build_vendor build_os host host_cpu host_vendor host_os HAVE_SUN_OS_TRUE HAVE_SUN_OS_FALSE HAVE_OSF1_OS_TRUE HAVE_OSF1_OS_FALSE HAVE_AIX_OS_TRUE HAVE_AIX_OS_FALSE HAVE_HPUX_OS_TRUE HAVE_HPUX_OS_FALSE HAVE_LINUX_OS_TRUE HAVE_LINUX_OS_FALSE HAVE_FREEBSD_OS_TRUE HAVE_FREEBSD_OS_FALSE HAVE_NETBSD_OS_TRUE HAVE_NETBSD_OS_FALSE HAVE_OPENBSD_OS_TRUE HAVE_OPENBSD_OS_FALSE HAVE_BSDI_OS_TRUE HAVE_BSDI_OS_FALSE HAVE_SGI_OS_TRUE HAVE_SGI_OS_FALSE HAVE_IRIX_OS_TRUE HAVE_IRIX_OS_FALSE HAVE_DARWIN_OS_TRUE HAVE_DARWIN_OS_FALSE SET_MAKE MKINSTALLDIRS USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE INTL_MACOSX_LIBS LIBICONV LTLIBICONV INTLLIBS LIBINTL LTLIBINTL POSUB GLIBC2 ALLOCA GLIBC21 HAVE_POSIX_PRINTF HAVE_ASPRINTF HAVE_SNPRINTF HAVE_WPRINTF INTLBISON BUILD_INCLUDED_LIBINTL USE_INCLUDED_LIBINTL CATOBJEXT DATADIRNAME INSTOBJEXT GENCAT INTLOBJS INTL_LIBTOOL_SUFFIX_PREFIX GNOME_INCLUDEDIR GNOMEUI_LIBS GNOME_LIBDIR GNOME_LIBS GNOME_DIR BAT_DIR QWT_INC QWT_LDFLAGS WXCONS_CPPFLAGS WXCONS_LDFLAGS WX_DIR TRAY_MONITOR_CPPFLAGS TRAY_MONITOR_LDFLAGS TRAY_MONITOR_DIR TTOOL_LDFLAGS STATIC_FD STATIC_SD STATIC_DIR STATIC_CONS STATIC_GNOME_CONS STATIC_WX_CONS ALL_DIRS DIRD_DIR DIR_TOOLS STORED_DIR CONS_INC CONS_OBJ CONS_SRC CONS_LIBS CONS_LDFLAGS READLINE_SRC PYTHON_LIBS PYTHON_INCDIR OPENSSL_LIBS OPENSSL_INC working_dir scriptdir dump_email job_email smtp_host piddir subsysdir baseport dir_port fd_port sd_port dir_password fd_password sd_password mon_dir_password mon_fd_password mon_sd_password db_name db_user dir_user dir_group sd_user sd_group fd_user fd_group SBINPERM SQL_LFLAGS SQL_INCLUDE SQL_BINDIR cats DB_TYPE GETCONF ac_ct_GETCONF X_CFLAGS X_PRE_LIBS X_LIBS X_EXTRA_LIBS LIBOBJS FDLIBS DEBUG DINCLUDE DLIB DB_LIBS WCFLAGS WLDFLAGS WRAPLIBS OBJLIST hostname TAPEDRIVE PSCMD WIN32 MACOSX DISTNAME DISTVER LTLIBOBJS'
- ac_subst_files='MCOMMON'
-
- # Initialize some variables set by options.
-@@ -350,8 +350,6 @@
- infodir='${prefix}/info'
- mandir='${prefix}/man'
-
--archivedir='/tmp'
--
- ac_prev=
- for ac_option
- do
-@@ -546,13 +544,6 @@
- | --sbi=* | --sb=*)
- sbindir=$ac_optarg ;;
-
-- -archivedir | --archivedir | --archivedi | --archived | --archive | --archiv \
-- | --archi | --arch | --arc | --ar | --a)
-- ac_prev=archivedir ;;
-- -archivedir=* | --archivedir=* | --archivedi=* | --archived=* | --archive=* \
-- | --archiv=* | --archi=* | --arch=* | --arc=* | --ar=* | --a=*)
-- archivedir=$ac_optarg ;;
--
- -sharedstatedir | --sharedstatedir | --sharedstatedi \
- | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
- | --sharedst | --shareds | --shared | --share | --shar \
-@@ -676,7 +667,7 @@
- done
-
- # Be sure to have absolute paths.
--for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir archivedir \
-+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
- localstatedir libdir includedir oldincludedir infodir mandir
- do
- eval ac_val=$`echo $ac_var`
-@@ -852,7 +843,6 @@
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --infodir=DIR info documentation [PREFIX/info]
- --mandir=DIR man documentation [PREFIX/man]
-- --archivedir=DIR archive destination for disk-based backups [/tmp]
- _ACEOF
-
- cat <<\_ACEOF
-@@ -4116,7 +4106,87 @@
- echo "${ECHO_T}no" >&6
- fi
-
-+# Extract the first word of "qmake", so it can be a program name with args.
-+set dummy qmake; ac_word=$2
-+echo "$as_me:$LINENO: checking for $ac_word" >&5
-+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-+if test "${ac_cv_path_QMAKE+set}" = set; then
-+ echo $ECHO_N "(cached) $ECHO_C" >&6
-+else
-+ case $QMAKE in
-+ [\\/]* | ?:[\\/]*)
-+ ac_cv_path_QMAKE="$QMAKE" # Let the user override the test with a path.
-+ ;;
-+ *)
-+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-+for as_dir in $PATH
-+do
-+ IFS=$as_save_IFS
-+ test -z "$as_dir" && as_dir=.
-+ for ac_exec_ext in '' $ac_executable_extensions; do
-+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-+ ac_cv_path_QMAKE="$as_dir/$ac_word$ac_exec_ext"
-+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-+ break 2
-+ fi
-+done
-+done
-
-+ test -z "$ac_cv_path_QMAKE" && ac_cv_path_QMAKE="none"
-+ ;;
-+esac
-+fi
-+QMAKE=$ac_cv_path_QMAKE
-+
-+if test -n "$QMAKE"; then
-+ echo "$as_me:$LINENO: result: $QMAKE" >&5
-+echo "${ECHO_T}$QMAKE" >&6
-+else
-+ echo "$as_me:$LINENO: result: no" >&5
-+echo "${ECHO_T}no" >&6
-+fi
-+
-+# Extract the first word of "qmake-qt4", so it can be a program name with args.
-+set dummy qmake-qt4; ac_word=$2
-+echo "$as_me:$LINENO: checking for $ac_word" >&5
-+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-+if test "${ac_cv_path_QMAKEQT4+set}" = set; then
-+ echo $ECHO_N "(cached) $ECHO_C" >&6
-+else
-+ case $QMAKEQT4 in
-+ [\\/]* | ?:[\\/]*)
-+ ac_cv_path_QMAKEQT4="$QMAKEQT4" # Let the user override the test with a path.
-+ ;;
-+ *)
-+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-+for as_dir in $PATH
-+do
-+ IFS=$as_save_IFS
-+ test -z "$as_dir" && as_dir=.
-+ for ac_exec_ext in '' $ac_executable_extensions; do
-+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-+ ac_cv_path_QMAKEQT4="$as_dir/$ac_word$ac_exec_ext"
-+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-+ break 2
-+ fi
-+done
-+done
-+
-+ test -z "$ac_cv_path_QMAKEQT4" && ac_cv_path_QMAKEQT4="none"
-+ ;;
-+esac
-+fi
-+QMAKEQT4=$ac_cv_path_QMAKEQT4
-+
-+if test -n "$QMAKEQT4"; then
-+ echo "$as_me:$LINENO: result: $QMAKEQT4" >&5
-+echo "${ECHO_T}$QMAKEQT4" >&6
-+else
-+ echo "$as_me:$LINENO: result: no" >&5
-+echo "${ECHO_T}no" >&6
-+fi
-+
-+
- if test "x$WXCONFIG" = x; then
- WXCONFIG=wx-config
- fi
-@@ -6776,8 +6846,8 @@
- # ------------------------------------------------------------------
- # If the user has not set --archivedir, we set our default as /tmp
- # ------------------------------------------------------------------
--if test x$archivedir = x'/tmp' ; then
-- archivedir=/tmp
-+if test x$archivedir = x'${archivedir}' ; then
-+ archivedir=${archivedir}
- fi
- archivedir=`eval echo ${archivedir}`
-
-@@ -19273,6 +19343,9 @@
-
-
-
-+
-+
-+
- for ac_header in \
- assert.h \
- fcntl.h \
-@@ -19284,6 +19357,7 @@
- stdlib.h \
- stdint.h \
- string.h \
-+ strings.h \
- termios.h \
- termcap.h \
- term.h \
-@@ -19292,9 +19366,11 @@
- sys/byteorder.h \
- sys/ioctl.h \
- sys/select.h \
-+ sys/socket.h \
- sys/sockio.h \
-+ sys/stat.h \
- sys/time.h \
-- sys/socket.h \
-+ sys/types.h \
- arpa/nameser.h \
- resolv.h \
- mtio.h \
-@@ -31173,7 +31249,6 @@
- s,@program_transform_name@,$program_transform_name,;t t
- s,@bindir@,$bindir,;t t
- s,@sbindir@,$sbindir,;t t
--s,@archivedir@,$archivedir,;t t
- s,@libexecdir@,$libexecdir,;t t
- s,@datadir@,$datadir,;t t
- s,@sysconfdir@,$sysconfdir,;t t
-@@ -31233,6 +31308,8 @@
- s,@DVDRWMEDIAINFO@,$DVDRWMEDIAINFO,;t t
- s,@DVDRWFORMAT@,$DVDRWFORMAT,;t t
- s,@PKGCONFIG@,$PKGCONFIG,;t t
-+s,@QMAKE@,$QMAKE,;t t
-+s,@QMAKEQT4@,$QMAKEQT4,;t t
- s,@WXCONFIG@,$WXCONFIG,;t t
- s,@WXFLAGS@,$WXFLAGS,;t t
- s,@CDRECORD@,$CDRECORD,;t t
-@@ -32122,10 +32199,23 @@
-
-
- if test "${support_bat}" = "yes" ; then
-+ if test "x$QMAKE" = "xnone" && test "x$QMAKEQT4" = "xnone"; then
-+ echo "Could not find qmake or qmake-qt4 in $PATH. Check your Qt installation"
-+ exit 1
-+ fi
-+
-+ QMAKEBIN="qmake"
-+
-+ if test "x$QMAKEQT4" != "xnone"; then
-+ QMAKEBIN=qmake-qt4
-+ fi
-+
-+
-+
- cd src/qt-console
- chmod 755 install_conf_file build-depkgs-qt-console
- echo "Creating bat Makefile"
-- qmake
-+ $QMAKEBIN
- cd ${BUILD_DIR}
- fi
-
-Index: src/bc_types.h
-===================================================================
---- src/bc_types.h (revision 5979)
-+++ src/bc_types.h (working copy)
-@@ -62,7 +62,7 @@
-
- #ifndef HAVE_INTXX_T
- # if (SIZEOF_CHAR == 1)
--typedef char int8_t;
-+typedef signed char int8_t;
- # else
- # error "8 bit int type not found."
- # endif
-Index: patches/2.2.6-queued-msg.patch
-===================================================================
---- patches/2.2.6-queued-msg.patch (revision 0)
-+++ patches/2.2.6-queued-msg.patch (revision 0)
-@@ -0,0 +1,25 @@
-+ This patch should ensure that queued messages to the console are
-+ displayed as soon as possible. It should fix bug 1007, but has been
-+ reported not to work.
-+
-+ Apply it to version 2.2.6 (or any prior 2.2.x) with:
-+
-+ cd <bacula-source>
-+ ./configure <your-options>
-+ patch -p0 <2.2.6-queued-msg.patch
-+ make
-+ ...
-+ make install
-+
-+Index: src/dird/ua_server.c
-+===================================================================
-+--- src/dird/ua_server.c (revision 5979)
-++++ src/dird/ua_server.c (working copy)
-+@@ -146,6 +146,7 @@
-+ } else {
-+ do_a_command(ua, ua->cmd);
-+ }
-++ dequeue_messages(ua->jcr);
-+ if (!ua->quit) {
-+ if (console_msg_pending && acl_access_ok(ua, Command_ACL, "messages", 8)) {
-+ if (ua->auto_display_messages) {
-Index: autoconf/configure.in
-===================================================================
---- autoconf/configure.in (revision 5979)
-+++ autoconf/configure.in (working copy)
-@@ -1394,6 +1394,7 @@
- stdlib.h \
- stdint.h \
- string.h \
-+ strings.h \
- termios.h \
- termcap.h \
- term.h \
-@@ -1402,9 +1403,11 @@
- sys/byteorder.h \
- sys/ioctl.h \
- sys/select.h \
-+ sys/socket.h \
- sys/sockio.h \
-+ sys/stat.h \
- sys/time.h \
-- sys/socket.h \
-+ sys/types.h \
- arpa/nameser.h \
- resolv.h \
- mtio.h \
+++ /dev/null
-
- This patch corrects a problem where the maximum concurrent storage
- jobs counter gets out of sync during restore jobs causing jobs to
- "wait on max Storage jobs". This patch fixes bug #1009.
-
- Apply this patch to 2.2.6 and probably any 2.2.x version with the
- following:
-
- cd <bacula-source>
- patch -p0 <2.2.6-maxconcurrentjobs.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/jobq.c
-===================================================================
---- src/dird/jobq.c (revision 6019)
-+++ src/dird/jobq.c (working copy)
-@@ -1,23 +1,4 @@
- /*
-- * Bacula job queue routines.
-- *
-- * This code consists of three queues, the waiting_jobs
-- * queue, where jobs are initially queued, the ready_jobs
-- * queue, where jobs are placed when all the resources are
-- * allocated and they can immediately be run, and the
-- * running queue where jobs are placed when they are
-- * running.
-- *
-- * Kern Sibbald, July MMIII
-- *
-- * Version $Id$
-- *
-- * This code was adapted from the Bacula workq, which was
-- * adapted from "Programming with POSIX Threads", by
-- * David R. Butenhof
-- *
-- */
--/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2003-2007 Free Software Foundation Europe e.V.
-@@ -44,6 +25,25 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ * Bacula job queue routines.
-+ *
-+ * This code consists of three queues, the waiting_jobs
-+ * queue, where jobs are initially queued, the ready_jobs
-+ * queue, where jobs are placed when all the resources are
-+ * allocated and they can immediately be run, and the
-+ * running queue where jobs are placed when they are
-+ * running.
-+ *
-+ * Kern Sibbald, July MMIII
-+ *
-+ * Version $Id$
-+ *
-+ * This code was adapted from the Bacula workq, which was
-+ * adapted from "Programming with POSIX Threads", by
-+ * David R. Butenhof
-+ *
-+ */
-
- #include "bacula.h"
- #include "dird.h"
-@@ -453,6 +453,7 @@
- }
- }
- jq->running_jobs->append(je);
-+// set_jcr_in_tsd(jcr);
- Dmsg1(2300, "Took jobid=%d from ready and appended to run\n", jcr->JobId);
-
- /* Release job queue lock */
-@@ -682,14 +683,13 @@
- jcr->acquired_resource_locks = false;
- if (jcr->rstore) {
- Dmsg1(200, "Rstore=%s\n", jcr->rstore->name());
-- if (jcr->rstore->NumConcurrentJobs == 0 &&
-- jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs) {
-- /* Simple case, first job */
-+ /*
-+ * Let only one Restore/Verify job run at a time regardless
-+ * of MaxConcurrentjobs.
-+ */
-+ if (jcr->rstore->NumConcurrentJobs == 0) {
- jcr->rstore->NumConcurrentJobs = 1;
- Dmsg0(200, "Set rncj=1\n");
-- } else if (jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs) {
-- jcr->rstore->NumConcurrentJobs++;
-- Dmsg1(200, "Inc rncj=%d\n", jcr->rstore->NumConcurrentJobs);
- } else {
- Dmsg1(200, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs);
- set_jcr_job_status(jcr, JS_WaitStoreRes);
-@@ -700,7 +700,7 @@
- if (jcr->wstore) {
- Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
- if (jcr->rstore == jcr->wstore) { /* deadlock */
-- jcr->rstore->NumConcurrentJobs--; /* back out rstore */
-+ jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
- Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
- " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"),
- jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
-@@ -716,7 +716,7 @@
- jcr->wstore->NumConcurrentJobs++;
- Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
- } else if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs--; /* back out rstore */
-+ jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
- Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
- skip_this_jcr = true;
- } else {
-@@ -738,7 +738,7 @@
- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
- }
- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs--;
-+ jcr->rstore->NumConcurrentJobs = 0;
- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
- }
- set_jcr_job_status(jcr, JS_WaitClientRes);
-@@ -753,7 +753,7 @@
- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
- }
- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs--;
-+ jcr->rstore->NumConcurrentJobs = 0;
- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
- }
- jcr->client->NumConcurrentJobs--;
+++ /dev/null
- This patch fixes bug #1012 where the job is canceled because
- of Max Run Time exceeded when the job has not yet started.
-
- Apply it to 2.2.6 or any prior 2.2.x version with:
-
- cd <bacula-source>
- patch -p0 <2.2.6-maxruntime.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (revision 5979)
-+++ src/dird/job.c (working copy)
-@@ -556,7 +556,7 @@
- */
- static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
- {
-- if (jcr->job->MaxRunTime == 0 || job_canceled(jcr)) {
-+ if (jcr->job->MaxRunTime == 0 || job_canceled(jcr) || jcr->JobStatus == JS_Created) {
- return false;
- }
- if ((watchdog_time - jcr->start_time) < jcr->job->MaxRunTime) {
-@@ -931,6 +931,7 @@
- {
- jcr->job = job;
- jcr->JobType = job->JobType;
-+ jcr->JobStatus = JS_Created;
- switch (jcr->JobType) {
- case JT_ADMIN:
- case JT_RESTORE:
+++ /dev/null
- This patch should ensure that queued messages to the console are
- displayed as soon as possible. It should fix bug 1007, but has been
- reported not to work.
-
- Apply it to version 2.2.6 (or any prior 2.2.x) with:
-
- cd <bacula-source>
- ./configure <your-options>
- patch -p0 <2.2.6-queued-msg.patch
- make
- ...
- make install
-
-Index: src/dird/ua_server.c
-===================================================================
---- src/dird/ua_server.c (revision 5979)
-+++ src/dird/ua_server.c (working copy)
-@@ -146,6 +146,7 @@
- } else {
- do_a_command(ua, ua->cmd);
- }
-+ dequeue_messages(ua->jcr);
- if (!ua->quit) {
- if (console_msg_pending && acl_access_ok(ua, Command_ACL, "messages", 8)) {
- if (ua->auto_display_messages) {
+++ /dev/null
-
- This patch prevents the "status dir" command from trying to use a scratch
- volume and possibly moving it from one pool to another. This patch fixes
- bug #1019.
-
- Apply the patch to 2.2.6 (and possibly any 2.2.x version with):
-
- cd <bacula-source>
- patch -p0 <2.2.6-scratch.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/next_vol.c
-===================================================================
---- src/dird/next_vol.c (revision 5999)
-+++ src/dird/next_vol.c (working copy)
-@@ -97,7 +97,7 @@
- prune_volumes(jcr, InChanger, mr);
- }
- ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
-- if (!ok) {
-+ if (!ok && create) {
- Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n",
- ok, index, InChanger, mr->VolStatus);
- /*
+++ /dev/null
- This patch fixes the status command to include the formating string for
- JS_AttrInsterting. It fixes bug #1021.
-
- Apply it to version 2.2.6 (and possibly earlier versions) with:
-
- cd <bacula-source>
- patch -p0 <2.2.6-status.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/ua_status.c
-===================================================================
---- src/dird/ua_status.c (revision 5979)
-+++ src/dird/ua_status.c (working copy)
-@@ -636,6 +636,12 @@
- case JS_WaitPriority:
- msg = _("is waiting for higher priority jobs to finish");
- break;
-+ case JS_AttrDespooling:
-+ msg = _("SD despooling Attributes");
-+ break;
-+ case JS_AttrInserting:
-+ msg = _("Dir inserting Attributes");
-+ break;
-
- default:
- emsg = (char *)get_pool_memory(PM_FNAME);
-@@ -673,8 +679,14 @@
- Mmsg(emsg, _("is waiting for Client %s to connect to Storage %s"),
- jcr->client->name(), jcr->wstore->name());
- }
-- msg = emsg;
-+ msg = emsg;
-+ break;
-+ case JS_AttrDespooling:
-+ msg = _("SD despooling Attributes");
- break;
-+ case JS_AttrInserting:
-+ msg = _("Dir inserting Attributes");
-+ break;
- }
- switch (jcr->JobType) {
- case JT_ADMIN:
+++ /dev/null
-
- This patch eliminates spurious output to the console during a VerifyVolume
- job that contains encrypted data.
- It fixes bug #1024.
-
- Apply this patch to Bacula version 2.2.6 and previous 2.2.x versions with:
-
- cd <bacula-source>
- patch -p0 <2.2.6-verify-vol.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/filed/verify_vol.c
-===================================================================
---- src/filed/verify_vol.c (revision 6010)
-+++ src/filed/verify_vol.c (working copy)
-@@ -211,19 +211,6 @@
- }
- break;
-
-- /* Data streams to ignore */
-- case STREAM_ENCRYPTED_SESSION_DATA:
-- case STREAM_FILE_DATA:
-- case STREAM_SPARSE_DATA:
-- case STREAM_WIN32_DATA:
-- case STREAM_WIN32_GZIP_DATA:
-- case STREAM_GZIP_DATA:
-- case STREAM_SPARSE_GZIP_DATA:
-- case STREAM_SIGNED_DIGEST:
--
-- /* Do nothing */
-- break;
--
- case STREAM_MD5_DIGEST:
- bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_MD5_SIZE, true);
- Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, digest);
-@@ -256,9 +243,10 @@
- Dmsg2(20, "bfiled>bdird: SHA512 len=%d: msg=%s\n", dir->msglen, dir->msg);
- break;
-
-+ /* Ignore everything else */
- default:
-- Pmsg2(0, "None of above!!! stream=%d data=%s\n", stream,sd->msg);
- break;
-+
- } /* end switch */
- } /* end while bnet_get */
- set_jcr_job_status(jcr, JS_Terminated);
+++ /dev/null
-
- This patch fixes a float point editing bug introduced in 2.2.7 (I think)
- causing the rate fields to be formated incorrectly (actually trunctated).
- This fixes bug #1036.
-
- Apply it to version 2.2.7 with:
-
- cd <bacula-source>
- patch -p0 <2.2.7-fpformat.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/lib/bsnprintf.c
-===================================================================
---- src/lib/bsnprintf.c (revision 6183)
-+++ src/lib/bsnprintf.c (working copy)
-@@ -16,7 +16,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2005-2008 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.
-@@ -566,11 +566,11 @@
- return result;
- }
-
--static long round(LDOUBLE value)
-+static int64_t round(LDOUBLE value)
- {
-- long intpart;
-+ int64_t intpart;
-
-- intpart = (long)value;
-+ intpart = (int64_t)value;
- value = value - intpart;
- if (value >= 0.5)
- intpart++;
-@@ -584,8 +584,8 @@
- int signvalue = 0;
- LDOUBLE ufvalue;
- #ifndef HAVE_FCVT
-- char iconvert[25];
-- char fconvert[25];
-+ char iconvert[311];
-+ char fconvert[311];
- #else
- char iconvert[311];
- char fconvert[311];
-@@ -602,6 +602,7 @@
- int caps = 0;
- int64_t intpart;
- int64_t fracpart;
-+ const char *cvt_str;
-
- /*
- * AIX manpage says the default is 0, but Solaris says the default
-@@ -625,7 +626,7 @@
- #endif
-
- #ifndef HAVE_FCVT
-- intpart = (long)ufvalue;
-+ intpart = (int64_t)ufvalue;
-
- /*
- * Sorry, we only support 9 digits past the decimal because of our
-@@ -645,28 +646,30 @@
- }
-
- #ifdef DEBUG_SNPRINTF
-- printf("fmtfp: %g %d.%d min=%d max=%d\n",
-+ printf("fmtfp: %g %lld.%lld min=%d max=%d\n",
- (double)fvalue, intpart, fracpart, min, max);
- #endif
-
- /* Convert integer part */
-+ cvt_str = caps ? "0123456789ABCDEF" : "0123456789abcdef";
- do {
-- iconvert[iplace++] =
-- (caps ? "0123456789ABCDEF" : "0123456789abcdef")[intpart % 10];
-+ iconvert[iplace++] = cvt_str[(int)(intpart % 10)];
- intpart = (intpart / 10);
-- } while (intpart && (iplace < (int)sizeof(iplace)));
-- if (iplace == (int)sizeof(iplace)) {
-+ } while (intpart && (iplace < (int)sizeof(iconvert)));
-+
-+ if (iplace == (int)sizeof(fconvert)) {
- iplace--;
- }
- iconvert[iplace] = 0;
-
- /* Convert fractional part */
-+ cvt_str = caps ? "0123456789ABCDEF" : "0123456789abcdef";
- do {
-- fconvert[fplace++] =
-- (caps ? "0123456789ABCDEF" : "0123456789abcdef")[fracpart % 10];
-+ fconvert[fplace++] = cvt_str[fracpart % 10];
- fracpart = (fracpart / 10);
-- } while (fracpart && (fplace < (int)sizeof(fplace)));
-- if (fplace == (int)sizeof(fplace)) {
-+ } while (fracpart && (fplace < (int)sizeof(fconvert)));
-+
-+ if (fplace == (int)sizeof(fconvert)) {
- fplace--;
- }
- fconvert[fplace] = 0;
-@@ -825,7 +828,7 @@
- NULL
- };
- double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
-- 0.9996, 1.996, 4.136, 6442452944.1234, 0
-+ 0.9996, 1.996, 4.136, 6442452944.1234, 0, 23365.5
- };
- #endif
- char *int_fmt[] = {
+++ /dev/null
-
- This patch permits to use migration options with JobDefs.
- This patch fixes bug #1028.
-
- Apply the patch to 2.2.7 (and possibly any 2.2.x version with):
-
- cd <bacula-source>
- patch -p0 <2.2.7-jobdefs-migtype.patch
- ./configure <your-options>
- make
- ...
- make install
-
-Index: src/dird/dird.c
-===================================================================
---- src/dird/dird.c (révision 6160)
-+++ src/dird/dird.c (copie de travail)
-@@ -58,6 +58,7 @@
- void store_jobtype(LEX *lc, RES_ITEM *item, int index, int pass);
- void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
- void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
-+void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
- void init_device_resources();
-
- static char *runjob = NULL;
-@@ -707,6 +708,7 @@
- job_items[i].handler == store_jobtype ||
- job_items[i].handler == store_level ||
- job_items[i].handler == store_pint ||
-+ job_items[i].handler == store_migtype ||
- job_items[i].handler == store_replace) {
- def_ivalue = (int *)((char *)(job->jobdefs) + offset);
- Dmsg5(400, "Job \"%s\", field \"%s\" def_ivalue=%d item %d offset=%u\n",
-Index: src/dird/dird_conf.c
-===================================================================
---- src/dird/dird_conf.c (révision 6160)
-+++ src/dird/dird_conf.c (copie de travail)
-@@ -74,8 +74,8 @@
- void store_level(LEX *lc, RES_ITEM *item, int index, int pass);
- void store_replace(LEX *lc, RES_ITEM *item, int index, int pass);
- void store_acl(LEX *lc, RES_ITEM *item, int index, int pass);
-+void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
- static void store_device(LEX *lc, RES_ITEM *item, int index, int pass);
--static void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass);
- static void store_runscript(LEX *lc, RES_ITEM *item, int index, int pass);
- static void store_runscript_when(LEX *lc, RES_ITEM *item, int index, int pass);
- static void store_runscript_cmd(LEX *lc, RES_ITEM *item, int index, int pass);
-@@ -1559,7 +1559,7 @@
- * Store JobType (backup, verify, restore)
- *
- */
--static void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass)
-+void store_migtype(LEX *lc, RES_ITEM *item, int index, int pass)
- {
- int token, i;
-
+++ /dev/null
-
- This patch fixes bug #1034 about Temporary MySQL table 'batch'
- disappears if MySQL connection times out.
-
- Apply the patch to 2.2.7 (and possibly any 2.2.x version with):
-
- cd <bacula-source>
- patch -p0 <2.2.7-mysql-batch-timeout.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/cats/mysql.c
-===================================================================
---- src/cats/mysql.c (révision 6192)
-+++ src/cats/mysql.c (copie de travail)
-@@ -205,6 +205,10 @@
- Dmsg3(100, "opendb ref=%d connected=%d db=%p\n", mdb->ref_count,
- mdb->connected, mdb->db);
-
-+ /* Set connection timeout to 8 days specialy for batch mode */
-+ sql_query(mdb, "SET wait_timeout=691200");
-+ sql_query(mdb, "SET interactive_timeout=691200");
-+
- V(mutex);
- return 1;
- }
+++ /dev/null
-
- If you have an old version of PostgreSQL, for example,
- version 7.3 or older, it may not properly build with the current
- Bacula release due to incompatible changes in the PostgreSQL
- header files between version. Only in the case that build fails,
- you might try applying this patch with:
-
- cd <bacula-2.2.7-source>
- patch -p1 <2.2.7-old-postgresql.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-diff -uNr bacula-2.2.7/src/cats/postgresql.c bacula-2.2.7-fixed/src/cats/postgresql.c
---- bacula-2.2.7/src/cats/postgresql.c 2007-12-08 04:54:55.000000000 -0500
-+++ bacula-2.2.7-fixed/src/cats/postgresql.c 2007-12-29 08:34:10.000000000 -0500
-@@ -47,7 +47,6 @@
- #ifdef HAVE_POSTGRESQL
-
- #include "postgres_ext.h" /* needed for NAMEDATALEN */
--#include "pg_config_manual.h" /* get NAMEDATALEN on version 8.3 or later */
-
- /* -----------------------------------------------------------------------
- *
+++ /dev/null
-
- This patch has a number of cleanups and improvements to the SD
- reservations system. It should fix a number of problems with
- dual drive autochangers as well ensure that volume use durations
- and max volume jobs are better respected.
-
- Apply it to version 2.2.7 (possibly some earlier versions) with:
-
- cd <bacula-source>
- patch -p1 <2.2.7-reserve.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-diff -ur k1/src/lib/message.c k3/src/lib/message.c
---- k1/src/lib/message.c 2007-10-19 13:47:58.000000000 +0200
-+++ k3/src/lib/message.c 2007-12-22 19:13:00.000000000 +0100
-@@ -54,6 +54,7 @@
- int verbose = 0; /* increase User messages */
- /* Keep debug level set to zero by default */
- int debug_level = 0; /* debug level */
-+bool dbg_timestamp = false; /* print timestamp in debug output */
- time_t daemon_start_time = 0; /* Daemon start time */
- const char *version = VERSION " (" BDATE ")";
- char my_name[30]; /* daemon name is stored here */
-diff -ur k1/src/lib/message.h k3/src/lib/message.h
---- k1/src/lib/message.h 2007-10-03 13:36:47.000000000 +0200
-+++ k3/src/lib/message.h 2007-12-22 19:13:06.000000000 +0100
-@@ -154,6 +154,7 @@
- extern DLL_IMP_EXP sql_escape p_sql_escape;
-
- extern DLL_IMP_EXP int debug_level;
-+extern DLL_IMP_EXP bool dbg_timestamp; /* print timestamp in debug output */
- extern DLL_IMP_EXP int verbose;
- extern DLL_IMP_EXP char my_name[];
- extern DLL_IMP_EXP const char * working_directory;
-diff -ur k1/src/stored/acquire.c k3/src/stored/acquire.c
---- k1/src/stored/acquire.c 2007-09-14 11:49:06.000000000 +0200
-+++ k3/src/stored/acquire.c 2007-12-22 19:12:23.000000000 +0100
-@@ -30,7 +30,7 @@
- *
- * Kern Sibbald, August MMII
- *
-- * Version $Id: acquire.c 5552 2007-09-14 09:49:06Z kerns $
-+ * Version $Id: acquire.c 6081 2007-12-21 14:11:40Z kerns $
- */
-
- #include "bacula.h" /* pull in global headers */
-@@ -38,6 +38,7 @@
-
- /* Forward referenced functions */
- static void attach_dcr_to_dev(DCR *dcr);
-+static bool is_suitable_volume_mounted(DCR *dcr);
-
-
- /*********************************************************************
-@@ -316,9 +317,9 @@
- */
- DCR *acquire_device_for_append(DCR *dcr)
- {
-- bool release = false;
-- bool recycle = false;
- bool do_mount = false;
-+ bool release = false;
-+ bool have_vol;
- DEVICE *dev = dcr->dev;
- JCR *jcr = dcr->jcr;
-
-@@ -337,6 +338,11 @@
- goto get_out;
- }
-
-+ /*
-+ * have_vol defines whether or not mount_next_write_volume should
-+ * ask the Director again about what Volume to use.
-+ */
-+ have_vol = is_suitable_volume_mounted(dcr);
- if (dev->can_append()) {
- Dmsg0(190, "device already in append.\n");
- /*
-@@ -351,25 +357,11 @@
- * dcr->VolumeName is what we pass into the routines, or
- * get back from the subroutines.
- */
-- bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
-- if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
-+ if (!have_vol &&
- !(dir_find_next_appendable_volume(dcr) &&
- strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
-- Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
-- dcr->VolumeName);
-- /* Release volume reserved by dir_find_next_appendable_volume() */
-- if (dcr->VolumeName[0]) {
-- volume_unused(dcr);
-- }
-- if (dev->num_writers != 0) {
-- Jmsg3(jcr, M_FATAL, 0, _("Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n"),
-- dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
-- Dmsg3(200, "Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n",
-- dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
-- goto get_out;
-- }
- /* Wrong tape mounted, release it, then fall through to get correct one */
-- Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
-+ Dmsg0(50, "Wrong tape mounted, release and try mount.\n");
- release = true;
- do_mount = true;
- } else {
-@@ -378,14 +370,17 @@
- * we do not need to do mount_next_write_volume(), unless
- * we need to recycle the tape.
- */
-- recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
-- Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
-- if (recycle && dev->num_writers != 0) {
-+ do_mount = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
-+ Dmsg2(190, "jid=%u Correct tape mounted. recycle=%d\n",
-+ (uint32_t)jcr->JobId, do_mount);
-+#ifdef xxx
-+ if (do_mount && dev->num_writers != 0) {
- Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
- " on device %s because it is in use by another job.\n"),
- dev->VolHdr.VolumeName, dev->print_name());
- goto get_out;
- }
-+#endif
- if (dev->num_writers == 0) {
- memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
- }
-@@ -415,21 +410,23 @@
- }
- } else {
- /* Not already in append mode, so mount the device */
-- Dmsg0(190, "Not in append mode, try mount.\n");
-+ Dmsg2(190, "jid=%u Not in append mode, try mount have_vol=%d\n",
-+ (uint32_t)jcr->JobId, have_vol);
-+
- ASSERT(dev->num_writers == 0);
- do_mount = true;
- }
-
-- if (do_mount || recycle) {
-- Dmsg0(190, "Do mount_next_write_vol\n");
-- bool mounted = mount_next_write_volume(dcr, release);
-+ if (do_mount || !have_vol) {
-+ Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId);
-+ bool mounted = mount_next_write_volume(dcr, have_vol, release);
- if (!mounted) {
- if (!job_canceled(jcr)) {
- /* Reduce "noise" -- don't print if job canceled */
- Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
- dev->print_name());
-- Dmsg1(200, "Could not ready device %s for append.\n",
-- dev->print_name());
-+ Dmsg2(200, "jid=%u Could not ready device %s for append.\n",
-+ (uint32_t)jcr->JobId, dev->print_name());
- }
- goto get_out;
- }
-@@ -441,11 +438,12 @@
- jcr->NumWriteVolumes = 1;
- }
- dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
-- dir_update_volume_info(dcr, false); /* send Volume info to Director */
-+ dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
- dev->dlock();
- if (dcr->reserved_device) {
- dev->reserved_device--;
-- Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
-+ Dmsg3(100, "jid=%u Dec reserve=%d dev=%s\n", (uint32_t)jcr->JobId,
-+ dev->reserved_device, dev->print_name());
- dcr->reserved_device = false;
- }
- dev->dunblock(DEV_LOCKED);
-@@ -458,7 +456,8 @@
- dev->dlock();
- if (dcr->reserved_device) {
- dev->reserved_device--;
-- Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
-+ Dmsg3(100, "jid=%u Dec reserve=%d dev=%s\n", (uint32_t)jcr->JobId,
-+ dev->reserved_device, dev->print_name());
- dcr->reserved_device = false;
- }
- dev->dunblock(DEV_LOCKED);
-@@ -466,6 +465,18 @@
- }
-
-
-+static bool is_suitable_volume_mounted(DCR *dcr)
-+{
-+ DEVICE *dev = dcr->dev;
-+
-+ /* Volume mounted? */
-+ if (dev->VolHdr.VolumeName[0] == 0) {
-+ return false; /* no */
-+ }
-+ bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
-+ return dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE);
-+}
-+
- /*
- * This job is done, so release the device. From a Unix standpoint,
- * the device remains open.
-@@ -496,7 +507,7 @@
- if (dev->can_read()) {
- dev->clear_read(); /* clear read bit */
- Dmsg0(100, "dir_update_vol_info. Release0\n");
-- dir_update_volume_info(dcr, false); /* send Volume info to Director */
-+ dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
-
- } else if (dev->num_writers > 0) {
- /*
-@@ -522,7 +533,7 @@
- dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
- /* Note! do volume update before close, which zaps VolCatInfo */
- Dmsg0(100, "dir_update_vol_info. Release0\n");
-- dir_update_volume_info(dcr, false); /* send Volume info to Director */
-+ dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
- }
- }
-
-@@ -621,7 +632,12 @@
- if (dcr->attached_to_dev) {
- detach_dcr_from_dev(dcr);
- }
-- dcr->max_job_spool_size = dev->device->max_job_spool_size;
-+ /* Use job spoolsize prior to device spoolsize */
-+ if (jcr->spool_size) {
-+ dcr->max_job_spool_size = jcr->spool_size;
-+ } else {
-+ dcr->max_job_spool_size = dev->device->max_job_spool_size;
-+ }
- dcr->device = dev->device;
- dcr->dev = dev;
- attach_dcr_to_dev(dcr);
-diff -ur k1/src/stored/askdir.c k3/src/stored/askdir.c
---- k1/src/stored/askdir.c 2007-09-09 12:03:23.000000000 +0200
-+++ k3/src/stored/askdir.c 2007-12-22 19:11:50.000000000 +0100
-@@ -31,7 +31,7 @@
- *
- * Kern Sibbald, December 2000
- *
-- * Version $Id: askdir.c 5503 2007-09-09 10:03:23Z kerns $
-+ * Version $Id: askdir.c 5852 2007-11-04 19:57:42Z kerns $
- */
-
- #include "bacula.h" /* pull in global headers */
-@@ -42,7 +42,7 @@
- static char Get_Vol_Info[] = "CatReq Job=%s GetVolInfo VolName=%s write=%d\n";
- static char Update_media[] = "CatReq Job=%s UpdateMedia VolName=%s"
- " VolJobs=%u VolFiles=%u VolBlocks=%u VolBytes=%s VolMounts=%u"
-- " VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%d VolStatus=%s"
-+ " VolErrors=%u VolWrites=%u MaxVolBytes=%s EndTime=%s VolStatus=%s"
- " Slot=%d relabel=%d InChanger=%d VolReadTime=%s VolWriteTime=%s"
- " VolFirstWritten=%s VolParts=%u\n";
- static char Create_job_media[] = "CatReq Job=%s CreateJobMedia"
-@@ -98,7 +98,7 @@
- } else {
- pm_strcpy(ChangerName, "*");
- }
-- ok =bnet_fsend(dir, Device_update,
-+ ok = dir->fsend(Device_update,
- jcr->Job,
- dev_name.c_str(),
- dev->can_append()!=0,
-@@ -125,7 +125,7 @@
- pm_strcpy(MediaType, device->media_type);
- bash_spaces(MediaType);
- /* This is mostly to indicate that we are here */
-- ok = bnet_fsend(dir, Device_update,
-+ ok = dir->fsend(Device_update,
- jcr->Job,
- dev_name.c_str(), /* Changer name */
- 0, 0, 0, /* append, read, num_writers */
-@@ -148,7 +148,7 @@
- */
- bool dir_send_job_status(JCR *jcr)
- {
-- return bnet_fsend(jcr->dir_bsock, Job_status, jcr->Job, jcr->JobStatus);
-+ return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus);
- }
-
- /*
-@@ -179,7 +179,7 @@
- return false;
- }
- memset(&vol, 0, sizeof(vol));
-- Dmsg1(100, "<dird %s\n", dir->msg);
-+ Dmsg1(100, "<dird %s", dir->msg);
- n = sscanf(dir->msg, OK_media, vol.VolCatName,
- &vol.VolCatJobs, &vol.VolCatFiles,
- &vol.VolCatBlocks, &vol.VolCatBytes,
-@@ -191,7 +191,8 @@
- &vol.EndFile, &vol.EndBlock, &vol.VolCatParts,
- &vol.LabelType, &vol.VolMediaId);
- if (n != 22) {
-- Dmsg3(100, "Bad response from Dir fields=%d, len=%d: %s", n, dir->msglen, dir->msg);
-+ Dmsg3(100, "Bad response from Dir fields=%d, len=%d: %s",
-+ n, dir->msglen, dir->msg);
- Mmsg(jcr->errmsg, _("Error getting Volume info: %s"), dir->msg);
- return false;
- }
-@@ -226,7 +227,7 @@
- bash_spaces(dcr->VolCatInfo.VolCatName);
- dir->fsend(Get_Vol_Info, jcr->Job, dcr->VolCatInfo.VolCatName,
- writing==GET_VOL_INFO_FOR_WRITE?1:0);
-- Dmsg1(100, ">dird: %s\n", dir->msg);
-+ Dmsg1(100, ">dird %s", dir->msg);
- unbash_spaces(dcr->VolCatInfo.VolCatName);
- bool ok = do_get_volume_info(dcr);
- V(vol_info_mutex);
-@@ -253,7 +254,9 @@
- BSOCK *dir = jcr->dir_bsock;
- bool found = false;
-
-- Dmsg0(200, "dir_find_next_appendable_volume\n");
-+ Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n",
-+ dcr->reserved_device, dcr->VolumeName);
-+
- /*
- * Try the twenty oldest or most available volumes. Note,
- * the most available could already be mounted on another
-@@ -268,7 +271,7 @@
- dir->fsend(Find_media, jcr->Job, vol_index, dcr->pool_name, dcr->media_type);
- unbash_spaces(dcr->media_type);
- unbash_spaces(dcr->pool_name);
-- Dmsg1(100, ">dird: %s", dir->msg);
-+ Dmsg1(100, ">dird %s", dir->msg);
- bool ok = do_get_volume_info(dcr);
- if (ok) {
- if (!is_volume_in_use(dcr)) {
-@@ -311,14 +314,13 @@
- * back to the director. The information comes from the
- * dev record.
- */
--bool dir_update_volume_info(DCR *dcr, bool label)
-+bool dir_update_volume_info(DCR *dcr, bool label, bool update_LastWritten)
- {
- JCR *jcr = dcr->jcr;
- BSOCK *dir = jcr->dir_bsock;
- DEVICE *dev = dcr->dev;
-- time_t LastWritten = time(NULL);
- VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
-- char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50];
-+ char ed1[50], ed2[50], ed3[50], ed4[50], ed5[50], ed6[50];
- int InChanger;
- bool ok = false;
- POOL_MEM VolumeName;
-@@ -341,21 +343,25 @@
- if (label) {
- bstrncpy(vol->VolCatStatus, "Append", sizeof(vol->VolCatStatus));
- }
-+// if (update_LastWritten) {
-+ vol->VolLastWritten = time(NULL);
-+// }
- pm_strcpy(VolumeName, vol->VolCatName);
- bash_spaces(VolumeName);
- InChanger = vol->InChanger;
-- bnet_fsend(dir, Update_media, jcr->Job,
-+ dir->fsend(Update_media, jcr->Job,
- VolumeName.c_str(), vol->VolCatJobs, vol->VolCatFiles,
- vol->VolCatBlocks, edit_uint64(vol->VolCatBytes, ed1),
- vol->VolCatMounts, vol->VolCatErrors,
- vol->VolCatWrites, edit_uint64(vol->VolCatMaxBytes, ed2),
-- LastWritten, vol->VolCatStatus, vol->Slot, label,
-+ edit_uint64(vol->VolLastWritten, ed6),
-+ vol->VolCatStatus, vol->Slot, label,
- InChanger, /* bool in structure */
- edit_int64(vol->VolReadTime, ed3),
- edit_int64(vol->VolWriteTime, ed4),
- edit_uint64(vol->VolFirstWritten, ed5),
- vol->VolCatParts);
-- Dmsg1(100, ">dird: %s", dir->msg);
-+ Dmsg1(100, ">dird %s", dir->msg);
-
- /* Do not lock device here because it may be locked from label */
- if (!do_get_volume_info(dcr)) {
-@@ -364,7 +370,7 @@
- vol->VolCatName, jcr->errmsg);
- goto bail_out;
- }
-- Dmsg1(420, "get_volume_info(): %s", dir->msg);
-+ Dmsg1(420, "get_volume_info() %s", dir->msg);
- /* Update dev Volume info in case something changed (e.g. expired) */
- dev->VolCatInfo = dcr->VolCatInfo;
- ok = true;
-@@ -393,20 +399,20 @@
- }
-
- dcr->WroteVol = false;
-- bnet_fsend(dir, Create_job_media, jcr->Job,
-+ dir->fsend(Create_job_media, jcr->Job,
- dcr->VolFirstIndex, dcr->VolLastIndex,
- dcr->StartFile, dcr->EndFile,
- dcr->StartBlock, dcr->EndBlock,
- dcr->Copy, dcr->Stripe,
- edit_uint64(dcr->VolMediaId, ed1));
-- Dmsg1(100, ">dird: %s", dir->msg);
-+ Dmsg1(100, ">dird %s", dir->msg);
- if (bnet_recv(dir) <= 0) {
- Dmsg0(190, "create_jobmedia error bnet_recv\n");
- Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"),
-- bnet_strerror(dir));
-+ dir->bstrerror());
- return false;
- }
-- Dmsg1(100, "<dir: %s", dir->msg);
-+ Dmsg1(100, "<dird %s", dir->msg);
- if (strcmp(dir->msg, OK_create) != 0) {
- Dmsg1(130, "Bad response from Dir: %s\n", dir->msg);
- Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: %s\n"), dir->msg);
-@@ -429,9 +435,10 @@
- return true;
- #endif
-
-- dir->msglen = sprintf(dir->msg, FileAttributes, jcr->Job);
-- dir->msg = check_pool_memory_size(dir->msg, dir->msglen +
-- sizeof(DEV_RECORD) + rec->data_len);
-+ dir->msg = check_pool_memory_size(dir->msg, sizeof(FileAttributes) +
-+ MAX_NAME_LENGTH + sizeof(DEV_RECORD) + rec->data_len + 1);
-+ dir->msglen = bsnprintf(dir->msg, sizeof(FileAttributes) +
-+ MAX_NAME_LENGTH + 1, FileAttributes, jcr->Job);
- ser_begin(dir->msg + dir->msglen, 0);
- ser_uint32(rec->VolSessionId);
- ser_uint32(rec->VolSessionTime);
-@@ -440,8 +447,8 @@
- ser_uint32(rec->data_len);
- ser_bytes(rec->data, rec->data_len);
- dir->msglen = ser_length(dir->msg);
-- Dmsg1(1800, ">dird: %s\n", dir->msg); /* Attributes */
-- return bnet_send(dir);
-+ Dmsg1(1800, ">dird %s\n", dir->msg); /* Attributes */
-+ return dir->send();
- }
-
-
-diff -ur k1/src/stored/bcopy.c k3/src/stored/bcopy.c
---- k1/src/stored/bcopy.c 2007-12-03 20:27:38.000000000 +0100
-+++ k3/src/stored/bcopy.c 2007-12-22 19:10:29.000000000 +0100
-@@ -32,7 +32,7 @@
- * Kern E. Sibbald, October 2002
- *
- *
-- * Version $Id: bcopy.c 6017 2007-12-03 19:27:38Z kerns $
-+ * Version $Id: bcopy.c 6016 2007-12-03 19:27:21Z kerns $
- */
-
- #include "bacula.h"
-@@ -42,6 +42,7 @@
- int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
-
- /* Forward referenced functions */
-+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec);
- static bool record_cb(DCR *dcr, DEV_RECORD *rec);
-
-
-@@ -52,10 +53,11 @@
- static JCR *out_jcr; /* output jcr */
- static BSR *bsr = NULL;
- static const char *wd = "/tmp";
--static int list_records = 0;
-+static bool list_records = false;
- static uint32_t records = 0;
- static uint32_t jobs = 0;
- static DEV_BLOCK *out_block;
-+static SESSION_LABEL sessrec;
-
- #define CONFIG_FILE "bacula-sd.conf"
- char *configfile = NULL;
-@@ -73,7 +75,7 @@
- "Usage: bcopy [-d debug_level] <input-archive> <output-archive>\n"
- " -b bootstrap specify a bootstrap file\n"
- " -c <file> specify configuration file\n"
--" -d <nn> set debug level to nn\n"
-+" -d <nn> set debug level to <nn>\n"
- " -i specify input Volume names (separated by |)\n"
- " -o specify output Volume names (separated by |)\n"
- " -p proceed inspite of errors\n"
-@@ -113,9 +115,14 @@
- break;
-
- case 'd': /* debug level */
-- debug_level = atoi(optarg);
-- if (debug_level <= 0)
-- debug_level = 1;
-+ if (*optarg == 't') {
-+ dbg_timestamp = true;
-+ } else {
-+ debug_level = atoi(optarg);
-+ if (debug_level <= 0) {
-+ debug_level = 1;
-+ }
-+ }
- break;
-
- case 'i': /* input Volume name */
-@@ -201,6 +208,7 @@
- out_block = out_jcr->dcr->block;
-
- ok = read_records(in_jcr->dcr, record_cb, mount_next_read_volume);
-+
- if (ok || out_dev->can_write()) {
- if (!write_block_to_device(out_jcr->dcr)) {
- Pmsg0(000, _("Write of last block failed.\n"));
-@@ -233,6 +241,7 @@
- *
- */
- if (rec->FileIndex < 0) {
-+ get_session_record(in_dcr->dev, rec, &sessrec);
-
- if (verbose > 1) {
- dump_label_record(in_dcr->dev, rec, 1);
-@@ -294,10 +303,46 @@
- return true;
- }
-
-+static void get_session_record(DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
-+{
-+ const char *rtype;
-+ memset(sessrec, 0, sizeof(sessrec));
-+ switch (rec->FileIndex) {
-+ case PRE_LABEL:
-+ rtype = _("Fresh Volume Label");
-+ break;
-+ case VOL_LABEL:
-+ rtype = _("Volume Label");
-+ unser_volume_label(dev, rec);
-+ break;
-+ case SOS_LABEL:
-+ rtype = _("Begin Job Session");
-+ unser_session_label(sessrec, rec);
-+ break;
-+ case EOS_LABEL:
-+ rtype = _("End Job Session");
-+ unser_session_label(sessrec, rec);
-+ break;
-+ case 0:
-+ case EOM_LABEL:
-+ rtype = _("End of Medium");
-+ break;
-+ default:
-+ rtype = _("Unknown");
-+ break;
-+ }
-+ Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
-+ rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
-+ if (verbose) {
-+ Pmsg5(-1, _("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n"),
-+ rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
-+ }
-+}
-+
-
- /* Dummies to replace askdir.c */
- bool dir_find_next_appendable_volume(DCR *dcr) { return 1;}
--bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; }
-+bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten) { return 1; }
- bool dir_create_jobmedia_record(DCR *dcr) { return 1; }
- bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
- bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
-diff -ur k1/src/stored/bextract.c k3/src/stored/bextract.c
---- k1/src/stored/bextract.c 2007-10-03 13:36:47.000000000 +0200
-+++ k3/src/stored/bextract.c 2007-12-22 19:10:20.000000000 +0100
-@@ -4,7 +4,7 @@
- *
- * Kern E. Sibbald, MM
- *
-- * Version $Id: bextract.c 5713 2007-10-03 11:36:47Z kerns $
-+ * Version $Id: bextract.c 5852 2007-11-04 19:57:42Z kerns $
- *
- */
- /*
-@@ -79,7 +79,7 @@
- "Usage: bextract <options> <bacula-archive-device-name> <directory-to-store-files>\n"
- " -b <file> specify a bootstrap file\n"
- " -c <file> specify a configuration file\n"
--" -d <nn> set debug level to nn\n"
-+" -d <nn> set debug level to <nn>\n"
- " -e <file> exclude list\n"
- " -i <file> include list\n"
- " -p proceed inspite of I/O errors\n"
-@@ -126,9 +126,14 @@
- break;
-
- case 'd': /* debug level */
-- debug_level = atoi(optarg);
-- if (debug_level <= 0)
-- debug_level = 1;
-+ if (*optarg == 't') {
-+ dbg_timestamp = true;
-+ } else {
-+ debug_level = atoi(optarg);
-+ if (debug_level <= 0) {
-+ debug_level = 1;
-+ }
-+ }
- break;
-
- case 'e': /* exclude list */
-@@ -476,7 +481,7 @@
-
- /* Dummies to replace askdir.c */
- bool dir_find_next_appendable_volume(DCR *dcr) { return 1;}
--bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; }
-+bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten) { return 1; }
- bool dir_create_jobmedia_record(DCR *dcr) { return 1; }
- bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
- bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
-diff -ur k1/src/stored/block.c k3/src/stored/block.c
---- k1/src/stored/block.c 2007-10-03 13:36:47.000000000 +0200
-+++ k3/src/stored/block.c 2007-12-22 19:12:33.000000000 +0100
-@@ -32,7 +32,7 @@
- * Kern Sibbald, March MMI
- * added BB02 format October MMII
- *
-- * Version $Id: block.c 5713 2007-10-03 11:36:47Z kerns $
-+ * Version $Id: block.c 5852 2007-11-04 19:57:42Z kerns $
- *
- */
-
-@@ -746,7 +746,7 @@
- dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
- }
-
-- if (!dir_update_volume_info(dcr, false)) {
-+ if (!dir_update_volume_info(dcr, false, true)) {
- ok = false;
- }
- Dmsg1(100, "dir_update_volume_info terminate writing -- %s\n", ok?"OK":"ERROR");
-@@ -798,7 +798,7 @@
- return false;
- }
- dev->VolCatInfo.VolCatFiles = dev->file;
-- if (!dir_update_volume_info(dcr, false)) {
-+ if (!dir_update_volume_info(dcr, false, false)) {
- Dmsg0(190, "Error from update_vol_info.\n");
- terminate_writing_volume(dcr);
- dev->dev_errno = EIO;
-@@ -856,7 +856,7 @@
-
- dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
-
-- if (!dir_update_volume_info(dcr, false)) {
-+ if (!dir_update_volume_info(dcr, false, false)) {
- Dmsg0(190, "Error from update_vol_info.\n");
- dev->dev_errno = EIO;
- return false;
-diff -ur k1/src/stored/bls.c k3/src/stored/bls.c
---- k1/src/stored/bls.c 2007-10-03 13:36:47.000000000 +0200
-+++ k3/src/stored/bls.c 2007-12-22 19:10:57.000000000 +0100
-@@ -31,7 +31,7 @@
- *
- * Kern Sibbald, MM
- *
-- * Version $Id: bls.c 5713 2007-10-03 11:36:47Z kerns $
-+ * Version $Id: bls.c 5852 2007-11-04 19:57:42Z kerns $
- */
-
- #include "bacula.h"
-@@ -79,7 +79,7 @@
- "Usage: bls [options] <device-name>\n"
- " -b <file> specify a bootstrap file\n"
- " -c <file> specify a config file\n"
--" -d <level> specify debug level\n"
-+" -d <nn> set debug level to <nn>\n"
- " -e <file> exclude list\n"
- " -i <file> include list\n"
- " -j list jobs\n"
-@@ -130,9 +130,14 @@
- break;
-
- case 'd': /* debug level */
-- debug_level = atoi(optarg);
-- if (debug_level <= 0)
-- debug_level = 1;
-+ if (*optarg == 't') {
-+ dbg_timestamp = true;
-+ } else {
-+ debug_level = atoi(optarg);
-+ if (debug_level <= 0) {
-+ debug_level = 1;
-+ }
-+ }
- break;
-
- case 'e': /* exclude list */
-@@ -440,7 +445,7 @@
-
- /* Dummies to replace askdir.c */
- bool dir_find_next_appendable_volume(DCR *dcr) { return 1;}
--bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; }
-+bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten) { return 1; }
- bool dir_create_jobmedia_record(DCR *dcr) { return 1; }
- bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
- bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
-diff -ur k1/src/stored/bscan.c k3/src/stored/bscan.c
---- k1/src/stored/bscan.c 2007-10-03 13:36:47.000000000 +0200
-+++ k3/src/stored/bscan.c 2007-12-22 19:11:05.000000000 +0100
-@@ -34,7 +34,7 @@
- * Kern E. Sibbald, December 2001
- *
- *
-- * Version $Id: bscan.c 5713 2007-10-03 11:36:47Z kerns $
-+ * Version $Id: bscan.c 5852 2007-11-04 19:57:42Z kerns $
- */
-
- #include "bacula.h"
-@@ -116,7 +116,7 @@
- "Usage: bscan [ options ] <bacula-archive>\n"
- " -b bootstrap specify a bootstrap file\n"
- " -c <file> specify configuration file\n"
--" -d <nn> set debug level to nn\n"
-+" -d <nn> set debug level to <nn>\n"
- " -m update media info in database\n"
- " -n <name> specify the database name (default bacula)\n"
- " -u <user> specify database user name (default bacula)\n"
-@@ -166,9 +166,14 @@
- break;
-
- case 'd': /* debug level */
-- debug_level = atoi(optarg);
-- if (debug_level <= 0)
-- debug_level = 1;
-+ if (*optarg == 't') {
-+ dbg_timestamp = true;
-+ } else {
-+ debug_level = atoi(optarg);
-+ if (debug_level <= 0) {
-+ debug_level = 1;
-+ }
-+ }
- break;
-
- case 'h':
-@@ -1271,7 +1276,7 @@
-
- /* Dummies to replace askdir.c */
- bool dir_find_next_appendable_volume(DCR *dcr) { return 1;}
--bool dir_update_volume_info(DCR *dcr, bool relabel) { return 1; }
-+bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten) { return 1; }
- bool dir_create_jobmedia_record(DCR *dcr) { return 1; }
- bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr) { return 1; }
- bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
-diff -ur k1/src/stored/btape.c k3/src/stored/btape.c
---- k1/src/stored/btape.c 2007-06-07 16:46:43.000000000 +0200
-+++ k3/src/stored/btape.c 2007-12-22 19:11:14.000000000 +0100
-@@ -37,7 +37,7 @@
- * Note, this program reads stored.conf, and will only
- * talk to devices that are configured.
- *
-- * Version $Id: btape.c 4992 2007-06-07 14:46:43Z kerns $
-+ * Version $Id: btape.c 5852 2007-11-04 19:57:42Z kerns $
- *
- */
-
-@@ -220,9 +220,13 @@
- break;
-
- case 'd': /* set debug level */
-- debug_level = atoi(optarg);
-- if (debug_level <= 0) {
-- debug_level = 1;
-+ if (*optarg == 't') {
-+ dbg_timestamp = true;
-+ } else {
-+ debug_level = atoi(optarg);
-+ if (debug_level <= 0) {
-+ debug_level = 1;
-+ }
- }
- break;
-
-@@ -2598,7 +2602,7 @@
- "Usage: btape <options> <device_name>\n"
- " -b <file> specify bootstrap file\n"
- " -c <file> set configuration file to file\n"
--" -d <nn> set debug level to nn\n"
-+" -d <nn> set debug level to <nn>\n"
- " -p proceed inspite of I/O errors\n"
- " -s turn off signals\n"
- " -v be verbose\n"
-@@ -2644,7 +2648,7 @@
- bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec) { return 1;}
- bool dir_send_job_status(JCR *jcr) {return 1;}
-
--bool dir_update_volume_info(DCR *dcr, bool relabel)
-+bool dir_update_volume_info(DCR *dcr, bool relabel, bool update_LastWritten)
- {
- return 1;
- }
-diff -ur k1/src/stored/dev.c k3/src/stored/dev.c
---- k1/src/stored/dev.c 2007-12-02 19:03:17.000000000 +0100
-+++ k3/src/stored/dev.c 2007-12-22 19:11:57.000000000 +0100
-@@ -47,7 +47,7 @@
- * daemon. More complicated coding (double buffering, writer
- * thread, ...) is left for a later version.
- *
-- * Version $Id: dev.c 6011 2007-12-02 18:03:17Z kerns $
-+ * Version $Id: dev.c 5999 2007-11-29 21:36:36Z ricozz $
- */
-
- /*
-@@ -89,7 +89,7 @@
- /* Forward referenced functions */
- void set_os_device_parameters(DCR *dcr);
- static bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat);
--static char *mode_to_str(int mode);
-+static const char *mode_to_str(int mode);
-
- /*
- * Allocate and initialize the DEVICE structure
-@@ -490,7 +490,7 @@
- Mmsg2(errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(),
- be.bstrerror());
- Dmsg1(100, "open failed: %s", errmsg);
-- Emsg0(M_FATAL, 0, errmsg);
-+ Jmsg1(NULL, M_WARNING, 0, "%s", errmsg);
- } else {
- dev_errno = 0;
- file = 0;
-@@ -2468,7 +2468,7 @@
- mt_stat->mt_fileno >= 0;
- }
-
--static char *modes[] = {
-+static const char *modes[] = {
- "CREATE_READ_WRITE",
- "OPEN_READ_WRITE",
- "OPEN_READ_ONLY",
-@@ -2476,7 +2476,7 @@
- };
-
-
--static char *mode_to_str(int mode)
-+static const char *mode_to_str(int mode)
- {
- static char buf[100];
- if (mode < 1 || mode > 4) {
-diff -ur k1/src/stored/dev.h k3/src/stored/dev.h
---- k1/src/stored/dev.h 2007-09-09 12:03:23.000000000 +0200
-+++ k3/src/stored/dev.h 2007-12-22 19:12:14.000000000 +0100
-@@ -31,7 +31,7 @@
- *
- * Kern Sibbald, MM
- *
-- * Version $Id: dev.h 5503 2007-09-09 10:03:23Z kerns $
-+ * Version $Id: dev.h 5852 2007-11-04 19:57:42Z kerns $
- *
- */
-
-@@ -158,6 +158,7 @@
- btime_t VolWriteTime; /* time spent writing this Volume */
- int64_t VolMediaId; /* MediaId */
- utime_t VolFirstWritten; /* Time of first write */
-+ utime_t VolLastWritten; /* Time of last write */
- bool InChanger; /* Set if vol in current magazine */
- char VolCatStatus[20]; /* Volume status */
- char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */
-@@ -473,8 +474,9 @@
- class VOLRES {
- public:
- dlink link;
-- char *vol_name;
-- DEVICE *dev;
-+ char *vol_name; /* Volume name */
-+ DEVICE *dev; /* Pointer to device to which we are attached */
-+ bool released; /* set when the Volume can be released */
- };
-
-
-diff -ur k1/src/stored/device.c k3/src/stored/device.c
---- k1/src/stored/device.c 2007-06-29 14:12:26.000000000 +0200
-+++ k3/src/stored/device.c 2007-12-22 19:11:23.000000000 +0100
-@@ -53,7 +53,7 @@
- *
- * Kern Sibbald, MM, MMI
- *
-- * Version $Id: device.c 5114 2007-06-29 12:12:26Z kerns $
-+ * Version $Id: device.c 5852 2007-11-04 19:57:42Z kerns $
- */
-
- #include "bacula.h" /* pull in global headers */
-@@ -122,7 +122,8 @@
- edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
- bstrftime(dt, sizeof(dt), time(NULL)));
-
-- if (!mount_next_write_volume(dcr, 1)) {
-+ /* Called with have_vol=false, release=true */
-+ if (!mount_next_write_volume(dcr, false, true)) {
- free_block(label_blk);
- dcr->block = block;
- dev->dlock();
-@@ -131,7 +132,7 @@
- dev->dlock(); /* lock again */
-
- dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
-- dir_update_volume_info(dcr, false); /* send Volume info to Director */
-+ dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
-
- Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
- dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
-diff -ur k1/src/stored/dvd.c k3/src/stored/dvd.c
---- k1/src/stored/dvd.c 2007-06-07 16:46:43.000000000 +0200
-+++ k3/src/stored/dvd.c 2007-12-22 19:26:23.000000000 +0100
-@@ -1,16 +1,7 @@
- /*
-- *
-- * dvd.c -- Routines specific to DVD devices (and
-- * possibly other removable hard media).
-- *
-- * Nicolas Boichat, MMV
-- *
-- * Version $Id: dvd.c 4992 2007-06-07 14:46:43Z kerns $
-- */
--/*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2005-2006 Free Software Foundation Europe e.V.
-+ Copyright (C) 2005-2007 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.
-@@ -34,6 +25,15 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ *
-+ * dvd.c -- Routines specific to DVD devices (and
-+ * possibly other removable hard media).
-+ *
-+ * Nicolas Boichat, MMV
-+ *
-+ * Version $Id: dvd.c 5852 2007-11-04 19:57:42Z kerns $
-+ */
-
- #include "bacula.h"
- #include "stored.h"
-@@ -686,7 +686,7 @@
- dcr->VolCatInfo.VolCatBytes = 0;
-
- /* Update catalog */
-- if (!dir_update_volume_info(dcr, false)) {
-+ if (!dir_update_volume_info(dcr, false, true)) {
- return false;
- }
-
-diff -ur k1/src/stored/job.c k3/src/stored/job.c
---- k1/src/stored/job.c 2007-09-29 00:01:16.000000000 +0200
-+++ k3/src/stored/job.c 2007-12-22 19:11:41.000000000 +0100
-@@ -30,7 +30,7 @@
- *
- * Kern Sibbald, MM
- *
-- * Version $Id: job.c 5686 2007-09-28 22:01:16Z kerns $
-+ * Version $Id: job.c 5697 2007-09-30 17:40:08Z ricozz $
- *
- */
-
-@@ -49,9 +49,13 @@
- /* Requests from the Director daemon */
- static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
- "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
-+ "SpoolData=%d WritePartAfterJob=%d PreferMountedVols=%d SpoolSize=%s\n";
-+static char oldjobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
-+ "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
- "SpoolData=%d WritePartAfterJob=%d PreferMountedVols=%d\n";
-
-
-+
- /* Responses sent to Director daemon */
- static char OKjob[] = "3000 OK Job SDid=%u SDtime=%u Authorization=%s\n";
- static char BAD_job[] = "3915 Bad Job command. stat=%d CMD: %s\n";
-@@ -73,6 +77,7 @@
- {
- int JobId;
- char auth_key[100];
-+ char spool_size[30];
- char seed[100];
- BSOCK *dir = jcr->dir_bsock;
- POOL_MEM job_name, client_name, job, fileset_name, fileset_md5;
-@@ -85,17 +90,26 @@
- * Get JobId and permissions from Director
- */
- Dmsg1(100, "<dird: %s", dir->msg);
-+ bstrncpy(spool_size, "0", sizeof(spool_size));
- stat = sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(),
- client_name.c_str(),
- &JobType, &level, fileset_name.c_str(), &no_attributes,
-- &spool_attributes, fileset_md5.c_str(), &spool_data,
-+ &spool_attributes, fileset_md5.c_str(), &spool_data,
-+ &write_part_after_job, &PreferMountedVols, spool_size);
-+ if (stat != 14) {
-+ /* Try old version */
-+ stat = sscanf(dir->msg, oldjobcmd, &JobId, job.c_str(), job_name.c_str(),
-+ client_name.c_str(),
-+ &JobType, &level, fileset_name.c_str(), &no_attributes,
-+ &spool_attributes, fileset_md5.c_str(), &spool_data,
- &write_part_after_job, &PreferMountedVols);
-- if (stat != 13) {
-- pm_strcpy(jcr->errmsg, dir->msg);
-- dir->fsend(BAD_job, stat, jcr->errmsg);
-- Dmsg1(100, ">dird: %s", dir->msg);
-- set_jcr_job_status(jcr, JS_ErrorTerminated);
-- return false;
-+ if (stat != 13) {
-+ pm_strcpy(jcr->errmsg, dir->msg);
-+ dir->fsend(BAD_job, stat, jcr->errmsg);
-+ Dmsg1(100, ">dird: %s", dir->msg);
-+ set_jcr_job_status(jcr, JS_ErrorTerminated);
-+ return false;
-+ }
- }
- /*
- * Since this job could be rescheduled, we
-@@ -125,6 +139,7 @@
- jcr->no_attributes = no_attributes;
- jcr->spool_attributes = spool_attributes;
- jcr->spool_data = spool_data;
-+ jcr->spool_size = str_to_int64(spool_size);
- jcr->write_part_after_job = write_part_after_job;
- jcr->fileset_md5 = get_pool_memory(PM_NAME);
- pm_strcpy(jcr->fileset_md5, fileset_md5);
-diff -ur k1/src/stored/label.c k3/src/stored/label.c
---- k1/src/stored/label.c 2007-10-03 13:36:47.000000000 +0200
-+++ k3/src/stored/label.c 2007-12-22 19:10:49.000000000 +0100
-@@ -32,7 +32,7 @@
- * Kern Sibbald, MM
- *
- *
-- * Version $Id: label.c 5713 2007-10-03 11:36:47Z kerns $
-+ * Version $Id: label.c 5852 2007-11-04 19:57:42Z kerns $
- */
-
- #include "bacula.h" /* pull in global headers */
-@@ -505,7 +505,7 @@
- }
- Dmsg0(150, "dir_update_vol_info. Set Append\n");
- bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus));
-- if (!dir_update_volume_info(dcr, true)) { /* indicate doing relabel */
-+ if (!dir_update_volume_info(dcr, true, true)) { /* indicate doing relabel */
- return false;
- }
- if (recycle) {
-@@ -716,7 +716,7 @@
- }
- break;
- default:
-- Jmsg1(jcr, M_ABORT, 0, _("Bad session label = %d\n"), label);
-+ Jmsg1(jcr, M_ABORT, 0, _("Bad Volume session label = %d\n"), label);
- break;
- }
- create_session_label(dcr, rec, label);
-diff -ur k1/src/stored/mount.c k3/src/stored/mount.c
---- k1/src/stored/mount.c 2007-09-14 11:49:06.000000000 +0200
-+++ k3/src/stored/mount.c 2007-12-22 19:11:30.000000000 +0100
-@@ -32,7 +32,7 @@
- *
- * Kern Sibbald, August MMII
- *
-- * Version $Id: mount.c 5552 2007-09-14 09:49:06Z kerns $
-+ * Version $Id: mount.c 5852 2007-11-04 19:57:42Z kerns $
- */
-
- #include "bacula.h" /* pull in global headers */
-@@ -60,7 +60,7 @@
- * impossible to get the requested Volume.
- *
- */
--bool mount_next_write_volume(DCR *dcr, bool release)
-+bool mount_next_write_volume(DCR *dcr, bool have_vol, bool release)
- {
- int retry = 0;
- bool ask = false, recycle, autochanger;
-@@ -108,12 +108,16 @@
- * in dcr->VolCatInfo
- */
- Dmsg0(200, "Before dir_find_next_appendable_volume.\n");
-- while (!dir_find_next_appendable_volume(dcr)) {
-- Dmsg0(200, "not dir_find_next\n");
-- if (!dir_ask_sysop_to_create_appendable_volume(dcr)) {
-- return false;
-+ if (!have_vol) {
-+ while (!dir_find_next_appendable_volume(dcr)) {
-+ Dmsg0(200, "not dir_find_next\n");
-+ if (!dir_ask_sysop_to_create_appendable_volume(dcr)) {
-+ return false;
-+ }
-+ Dmsg0(200, "Again dir_find_next_append...\n");
- }
-- Dmsg0(200, "Again dir_find_next_append...\n");
-+ } else {
-+ have_vol = false; /* set false for next pass if any */
- }
- if (job_canceled(jcr)) {
- return false;
-@@ -144,7 +148,7 @@
- * If we autochanged to correct Volume or (we have not just
- * released the Volume AND we can automount) we go ahead
- * and read the label. If there is no tape in the drive,
-- * we will err, recurse and ask the operator the next time.
-+ * we will fail, recurse and ask the operator the next time.
- */
- if (!release && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
- Dmsg0(150, "(1)Ask=0\n");
-@@ -432,7 +436,7 @@
- }
- dev->VolCatInfo.VolCatMounts++; /* Update mounts */
- Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
-- if (!dir_update_volume_info(dcr, false)) {
-+ if (!dir_update_volume_info(dcr, false, false)) {
- return false;
- }
-
-@@ -519,7 +523,7 @@
- Dmsg0(150, "dir_update_vol_info. Set Append\n");
- /* Copy Director's info into the device info */
- dev->VolCatInfo = dcr->VolCatInfo; /* structure assignment */
-- if (!dir_update_volume_info(dcr, true)) { /* indicate tape labeled */
-+ if (!dir_update_volume_info(dcr, true, true)) { /* indicate tape labeled */
- return try_error;
- }
- Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
-@@ -552,7 +556,7 @@
- dev->VolCatInfo = dcr->VolCatInfo; /* structure assignment */
- bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
- Dmsg0(150, "dir_update_vol_info. Set Error.\n");
-- dir_update_volume_info(dcr, false);
-+ dir_update_volume_info(dcr, false, false);
- }
-
- /*
-@@ -570,7 +574,7 @@
- dcr->VolCatInfo.InChanger = false;
- dev->VolCatInfo.InChanger = false;
- Dmsg0(400, "update vol info in mount\n");
-- dir_update_volume_info(dcr, true); /* set new status */
-+ dir_update_volume_info(dcr, true, false); /* set new status */
- }
-
- /*
-@@ -588,6 +592,7 @@
- /*
- * First erase all memory of the current volume
- */
-+ free_volume(dev);
- dev->block_num = dev->file = 0;
- dev->EndBlock = dev->EndFile = 0;
- memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
-diff -ur k1/src/stored/protos.h k3/src/stored/protos.h
---- k1/src/stored/protos.h 2007-06-28 13:57:03.000000000 +0200
-+++ k3/src/stored/protos.h 2007-12-22 19:12:43.000000000 +0100
-@@ -28,7 +28,7 @@
- /*
- * Protypes for stored -- Kern Sibbald MM
- *
-- * Version $Id: protos.h 5112 2007-06-28 11:57:03Z kerns $
-+ * Version $Id: protos.h 5852 2007-11-04 19:57:42Z kerns $
- */
-
- /* From stored.c */
-@@ -49,7 +49,7 @@
- };
- bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
- bool dir_find_next_appendable_volume(DCR *dcr);
--bool dir_update_volume_info(DCR *dcr, bool label);
-+bool dir_update_volume_info(DCR *dcr, bool label, bool update_LastWritten);
- bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
- bool dir_ask_sysop_to_mount_volume(DCR *dcr);
- bool dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
-@@ -182,7 +182,7 @@
- bool is_this_bsr_done(BSR *bsr, DEV_RECORD *rec);
-
- /* From mount.c */
--bool mount_next_write_volume(DCR *dcr, bool release);
-+bool mount_next_write_volume(DCR *dcr, bool have_vol, bool release);
- bool mount_next_read_volume(DCR *dcr);
- void mark_volume_in_error(DCR *dcr);
-
-diff -ur k1/src/stored/record.c k3/src/stored/record.c
---- k1/src/stored/record.c 2007-06-07 16:46:43.000000000 +0200
-+++ k3/src/stored/record.c 2007-12-22 19:12:06.000000000 +0100
-@@ -1,14 +1,4 @@
- /*
-- *
-- * record.c -- tape record handling functions
-- *
-- * Kern Sibbald, April MMI
-- * added BB02 format October MMII
-- *
-- * Version $Id: record.c 4992 2007-06-07 14:46:43Z kerns $
-- *
-- */
--/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2001-2006 Free Software Foundation Europe e.V.
-@@ -35,6 +25,16 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ *
-+ * record.c -- tape record handling functions
-+ *
-+ * Kern Sibbald, April MMI
-+ * added BB02 format October MMII
-+ *
-+ * Version $Id: record.c 6014 2007-12-03 18:14:27Z kerns $
-+ *
-+ */
-
-
- #include "bacula.h"
-@@ -254,7 +254,7 @@
- ASSERT(block->buf_len >= block->binbuf);
-
- Dmsg6(890, "write_record_to_block() FI=%s SessId=%d Strm=%s len=%d\n"
--"rem=%d remainder=%d\n",
-+ "rem=%d remainder=%d\n",
- FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
- stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len,
- remlen, rec->remainder);
-@@ -365,7 +365,7 @@
- if (!sm_check_rtn(__FILE__, __LINE__, False)) {
- /* We damaged a buffer */
- Dmsg6(0, "Damaged block FI=%s SessId=%d Strm=%s len=%d\n"
--"rem=%d remainder=%d\n",
-+ "rem=%d remainder=%d\n",
- FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
- stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len,
- remlen, rec->remainder);
-diff -ur k1/src/stored/reserve.c k3/src/stored/reserve.c
---- k1/src/stored/reserve.c 2007-08-04 18:46:32.000000000 +0200
-+++ k3/src/stored/reserve.c 2007-12-22 19:09:56.000000000 +0100
-@@ -212,11 +212,11 @@
- if (dev) {
- len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name());
- sendit(msg.c_str(), len, arg);
-- len = Mmsg(msg, " Reader=%d writers=%d reserved=%d\n", dev->can_read()?1:0,
-- dev->num_writers, dev->reserved_device);
-+ len = Mmsg(msg, " Reader=%d writers=%d reserved=%d released=%d\n",
-+ dev->can_read()?1:0, dev->num_writers, dev->reserved_device, vol->released);
- sendit(msg.c_str(), len, arg);
- } else {
-- len = Mmsg(msg, "%s no dev\n", vol->vol_name);
-+ len = Mmsg(msg, "%s no device. released=%d\n", vol->vol_name, vol->released);
- sendit(msg.c_str(), len, arg);
- }
- }
-@@ -292,11 +292,11 @@
- * already exist and are correctly programmed and will need no changes -- use
- * counts are always very tricky.
- *
-- * The old code had a concept of "reserving" a Volume, but it needs to be changed
-+ * The old code had a concept of "reserving" a Volume, but was changed
- * to reserving and using a drive. A volume is must be attached to (owned by) a
- * drive and can move from drive to drive or be unused given certain specific
- * conditions of the drive. The key is that the drive must "own" the Volume.
-- * The old code has the job (dcr) owning the volume (more or less). The job is
-+ * The old code had the job (dcr) owning the volume (more or less). The job was
- * to change the insertion and removal of the volumes from the list to be based
- * on the drive rather than the job.
- *
-@@ -329,13 +329,14 @@
- * because it was probably inserted by another job.
- */
- if (strcmp(vol->vol_name, VolumeName) == 0) {
-+ Dmsg1(dbglvl, "OK, vol=%s on device.\n", VolumeName);
- goto get_out; /* Volume already on this device */
- } else {
-- Dmsg3(dbglvl, "jid=%u reserve_vol free vol=%s at %p\n",
-+ Dmsg3(dbglvl, "jid=%u reserve_vol free vol=%s at %p\n",
- (int)dcr->jcr->JobId, vol->vol_name, vol->vol_name);
-- debug_list_volumes("reserve_vol free");
- vol_list->remove(vol);
- free_vol_item(vol);
-+ debug_list_volumes("reserve_vol free");
- }
- }
-
-@@ -378,12 +379,16 @@
- Dmsg4(dbglvl, "jid=%u Volume busy could not swap vol=%s from dev=%s to %s\n",
- jid(), VolumeName, vol->dev->print_name(), dev->print_name());
- vol = NULL; /* device busy */
-+ goto get_out;
- }
- }
- }
- dev->vol = vol;
-
- get_out:
-+ if (vol) {
-+ vol->released = false;
-+ }
- debug_list_volumes("end new volume");
- unlock_volumes();
- return vol;
-@@ -462,6 +467,7 @@
- * explicitly read in this drive. This allows the SD to remember
- * where the tapes are or last were.
- */
-+ dev->vol->released = true;
- if (dev->is_tape() || dev->is_autochanger()) {
- return true;
- } else {
-@@ -837,6 +843,7 @@
- dlist *temp_vol_list, *save_vol_list;
- VOLRES *vol = NULL;
- lock_volumes();
-+ Dmsg0(dbglvl, "lock volumes\n");
-
- /*
- * Create a temporary copy of the volume list. We do this,
-@@ -1122,6 +1129,26 @@
- */
- if (dcr->volume_in_use && !rctx.PreferMountedVols) {
- rctx.PreferMountedVols = true;
-+ if (dcr->VolumeName[0]) {
-+ volume_unused(dcr);
-+ }
-+ goto bail_out;
-+ }
-+ /*
-+ * Note. Under some circumstances, the Director can hand us
-+ * a Volume name that is no the same as the one on the current
-+ * drive, and in that case, the call above to find the next
-+ * volume will fail because in attempting to reserve the Volume
-+ * the code will realize that we already have a tape mounted,
-+ * and it will fail. This *should* only happen if there are
-+ * writers, thus the following test. In that case, we simply
-+ * bail out, and continue waiting, rather than plunging on
-+ * and hoping that the operator can resolve the problem.
-+ */
-+ if (dcr->dev->num_writers != 0) {
-+ if (dcr->VolumeName[0]) {
-+ volume_unused(dcr);
-+ }
- goto bail_out;
- }
- }
-@@ -1270,6 +1297,51 @@
- return ok;
- }
-
-+static int is_pool_ok(DCR *dcr)
-+{
-+ DEVICE *dev = dcr->dev;
-+ JCR *jcr = dcr->jcr;
-+
-+ /* Now check if we want the same Pool and pool type */
-+ if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
-+ strcmp(dev->pool_type, dcr->pool_type) == 0) {
-+ /* OK, compatible device */
-+ Dmsg1(dbglvl, "OK dev: %s num_writers=0, reserved, pool matches\n", dev->print_name());
-+ return 1;
-+ } else {
-+ /* Drive Pool not suitable for us */
-+ Mmsg(jcr->errmsg, _(
-+"3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
-+ (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
-+ dev->reserved_device, dev->print_name());
-+ queue_reserve_message(jcr);
-+ Dmsg2(dbglvl, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
-+ dev->pool_name, dcr->pool_name);
-+ }
-+ return 0;
-+}
-+
-+static bool is_max_jobs_ok(DCR *dcr)
-+{
-+ DEVICE *dev = dcr->dev;
-+ JCR *jcr = dcr->jcr;
-+
-+ Dmsg4(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Vol=%s\n",
-+ dcr->VolCatInfo.VolCatMaxJobs,
-+ dcr->VolCatInfo.VolCatJobs, dev->reserved_device,
-+ dcr->VolumeName);
-+ if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <=
-+ (dcr->VolCatInfo.VolCatJobs + dev->reserved_device)) {
-+ /* Max Job Vols depassed or already reserved */
-+ Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"),
-+ (uint32_t)jcr->JobId, dev->print_name());
-+ queue_reserve_message(jcr);
-+ Dmsg1(dbglvl, "reserve dev failed: %s", jcr->errmsg);
-+ return false; /* wait */
-+ }
-+ return true;
-+}
-+
- /*
- * Returns: 1 if drive can be reserved
- * 0 if we should wait
-@@ -1285,6 +1357,11 @@
- rctx.PreferMountedVols, rctx.exact_match, rctx.suitable_device,
- rctx.autochanger_only, rctx.any_drive);
-
-+ /* Check for max jobs on this Volume */
-+ if (!is_max_jobs_ok(dcr)) {
-+ return 0;
-+ }
-+
- /* setting any_drive overrides PreferMountedVols flag */
- if (!rctx.any_drive) {
- /*
-@@ -1374,32 +1451,10 @@
- if (dev->num_writers == 0) {
- /* Now check if there are any reservations on the drive */
- if (dev->reserved_device) {
-- /* Now check if we want the same Pool and pool type */
-- if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
-- strcmp(dev->pool_type, dcr->pool_type) == 0) {
-- /* OK, compatible device */
-- Dmsg2(dbglvl, "jid=%u OK dev: %s num_writers=0, reserved, pool matches\n",
-- jcr->JobId, dev->print_name());
-- return 1;
-- } else {
-- /* Drive Pool not suitable for us */
-- Mmsg(jcr->errmsg, _(
--"3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"),
-- jcr->JobId, dcr->pool_name, dev->pool_name,
-- dev->reserved_device, dev->print_name());
-- queue_reserve_message(jcr);
-- Dmsg3(dbglvl, "jid=%u failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
-- (int)jcr->JobId, dev->pool_name, dcr->pool_name);
-- return 0; /* wait */
-- }
-+ return is_pool_ok(dcr);
- } else if (dev->can_append()) {
-- /* Device in append mode, check if changing pool */
-- if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
-- strcmp(dev->pool_type, dcr->pool_type) == 0) {
-- Dmsg2(dbglvl, "jid=%u OK dev: %s num_writers=0, can_append, pool matches.\n",
-- jcr->JobId, dev->print_name());
-- /* OK, compatible device */
-- return 1;
-+ if (is_pool_ok(dcr)) {
-+ return 1;
- } else {
- /* Changing pool, unload old tape if any in drive */
- Dmsg1(dbglvl, "jid=%u OK dev: num_writers=0, not reserved, pool change, unload changer\n",
-@@ -1419,22 +1474,7 @@
- * available if pool is the same).
- */
- if (dev->can_append() || dev->num_writers > 0) {
-- /* Yes, now check if we want the same Pool and pool type */
-- if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
-- strcmp(dev->pool_type, dcr->pool_type) == 0) {
-- Dmsg2(dbglvl, "jid=%u OK dev: %s num_writers>=0, can_append, pool matches.\n",
-- jcr->JobId, dev->print_name());
-- /* OK, compatible device */
-- return 1;
-- } else {
-- /* Drive Pool not suitable for us */
-- Mmsg(jcr->errmsg, _("3609 JobId=%u wants Pool=\"%s\" but has Pool=\"%s\" on drive %s.\n"),
-- jcr->JobId, dcr->pool_name, dev->pool_name, dev->print_name());
-- queue_reserve_message(jcr);
-- Dmsg3(dbglvl, "jid=%u failed: busy num_writers>0, can_append, pool=%s wanted=%s\n",
-- (int)jcr->JobId, dev->pool_name, dcr->pool_name);
-- return 0; /* wait */
-- }
-+ return is_pool_ok(dcr);
- } else {
- Pmsg1(000, _("Logic error!!!! JobId=%u Should not get here.\n"), (int)jcr->JobId);
- Mmsg(jcr->errmsg, _("3910 JobId=%u Logic error!!!! drive %s Should not get here.\n"),
+++ /dev/null
-
- This patch automatically adds the Bacula database and user name to
- the default make_catalog_backup Run script call line in the bacula-dir.conf
- file.
-
- Apply it to version 2.2.8 or earlier with:
-
- cd <bacula-source>
- patch -p0 <2.2.8-bacula-conf.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/bacula-dir.conf.in
-===================================================================
---- src/dird/bacula-dir.conf.in (revision 6327)
-+++ src/dird/bacula-dir.conf.in (working copy)
-@@ -61,7 +61,11 @@
- FileSet="Catalog"
- Schedule = "WeeklyCycleAfterBackup"
- # This creates an ASCII copy of the catalog
-- RunBeforeJob = "@scriptdir@/make_catalog_backup bacula bacula"
-+ # WARNING!!! Passing the password via the command line is insecure.
-+ # see comments in make_catalog_backup for details.
-+ # Arguments to make_catalog_backup are:
-+ # make_catalog_backup <database-name> <user-name> <password> <host>
-+ RunBeforeJob = "@scriptdir@/make_catalog_backup @db_name@ @db_user@"
- # This deletes the copy of the catalog
- RunAfterJob = "@scriptdir@/delete_catalog_backup"
- Write Bootstrap = "@working_dir@/BackupCatalog.bsr"
+++ /dev/null
-
- This patch fixes two deadlock conditions that occur in Bacula.
- The first is caused by running simultaneous backup and restore jobs
- with an autochanger, and leads to use counts getting out of sync causing
- jobs in the Director to wait on resources.
- The second is a condition where the SD is unable to use a Volume that
- is currently mounted because it keeps wanting a different Volume. This
- condition seems to be relatively rare unless you are using
- "Prefer Mounted Volumes = no" in which case it occurs much more often.
-
- This patch can be applied to a fully patched 2.2.8 version with the
- following:
-
- cd <bacula-source>
- patch -p0 <2.2.8-deadlock.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/jobq.c
-===================================================================
---- src/dird/jobq.c (revision 6531)
-+++ src/dird/jobq.c (working copy)
-@@ -478,7 +478,7 @@
- */
- if (jcr->acquired_resource_locks) {
- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs = 0;
-+ jcr->rstore->NumConcurrentJobs--;
- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
- }
- if (jcr->wstore) {
-Index: src/stored/askdir.c
-===================================================================
---- src/stored/askdir.c (revision 6531)
-+++ src/stored/askdir.c (working copy)
-@@ -252,20 +252,19 @@
- {
- JCR *jcr = dcr->jcr;
- BSOCK *dir = jcr->dir_bsock;
-- bool found = false;
-
- Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n",
- dcr->reserved_device, dcr->VolumeName);
-
- /*
-- * Try the twenty oldest or most available volumes. Note,
-+ * Try the fourty oldest or most available volumes. Note,
- * the most available could already be mounted on another
- * drive, so we continue looking for a not in use Volume.
- */
- lock_reservations();
- P(vol_info_mutex);
- dcr->volume_in_use = false;
-- for (int vol_index=1; vol_index < 20; vol_index++) {
-+ for (int vol_index=1; vol_index < 40; vol_index++) {
- bash_spaces(dcr->media_type);
- bash_spaces(dcr->pool_name);
- dir->fsend(Find_media, jcr->Job, vol_index, dcr->pool_name, dcr->media_type);
-@@ -275,33 +274,26 @@
- bool ok = do_get_volume_info(dcr);
- if (ok) {
- if (!is_volume_in_use(dcr)) {
-- found = true;
-- break;
-+ Dmsg0(400, "dir_find_next_appendable_volume return true\n");
-+ if (reserve_volume(dcr, dcr->VolumeName) == 0) {
-+ Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
-+ dcr->dev->print_name());
-+ continue;
-+ }
-+ V(vol_info_mutex);
-+ unlock_reservations();
-+ return true;
- } else {
- Dmsg1(100, "Volume %s is in use.\n", dcr->VolumeName);
- dcr->volume_in_use = true;
- continue;
- }
-- } else {
-- Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index,
-- dcr->dev->print_name());
-- found = false;
-- break;
- }
-+ Dmsg2(100, "No vol. index %d return false. dev=%s\n", vol_index,
-+ dcr->dev->print_name());
-+ break;
- }
-- if (found) {
-- Dmsg0(400, "dir_find_next_appendable_volume return true\n");
-- if (reserve_volume(dcr, dcr->VolumeName) == 0) {
-- Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
-- dcr->dev->print_name());
-- goto bail_out;
-- }
-- V(vol_info_mutex);
-- unlock_reservations();
-- return true;
-- }
-
--bail_out:
- dcr->VolumeName[0] = 0;
- V(vol_info_mutex);
- unlock_reservations();
-Index: src/stored/acquire.c
-===================================================================
---- src/stored/acquire.c (revision 6531)
-+++ src/stored/acquire.c (working copy)
-@@ -362,7 +362,10 @@
- strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
- /* Wrong tape mounted, release it, then fall through to get correct one */
- Dmsg0(50, "Wrong tape mounted, release and try mount.\n");
-- release = true;
-+ /* Do not release if no Volume in drive */
-+ if (dev->VolHdr.VolumeName[0]) {
-+ release = true;
-+ }
- do_mount = true;
- } else {
- /*
+++ /dev/null
-
- This patch fixes a migration bug that always has a zero index entry
- (JobMedia record) as the first entry. This causes Bacula to search
- for the first record during a restore rather than seek directly to
- it.
-
- Apply this patch to Bacula 2.2.8 (and possibly any prior 2.2.x version) with:
-
- cd <bacula-source>
- patch -p0 <2.2.8-jobmedia.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/stored/device.c
-===================================================================
---- src/stored/device.c (revision 6391)
-+++ src/stored/device.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2007 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.
-@@ -200,6 +200,19 @@
- return ok; /* device locked */
- }
-
-+void set_start_vol_position(DCR *dcr)
-+{
-+ DEVICE *dev = dcr->dev;
-+ /* Set new start position */
-+ if (dev->is_tape()) {
-+ dcr->StartBlock = dev->block_num;
-+ dcr->StartFile = dev->file;
-+ } else {
-+ dcr->StartBlock = (uint32_t)dev->file_addr;
-+ dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
-+ }
-+}
-+
- /*
- * We have a new Volume mounted, so reset the Volume parameters
- * concerning this job. The global changes were made earlier
-@@ -208,24 +221,11 @@
- void set_new_volume_parameters(DCR *dcr)
- {
- JCR *jcr = dcr->jcr;
-- DEVICE *dev = dcr->dev;
- if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
- Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
- }
-- /* Set new start/end positions */
-- if (dev->is_tape()) {
-- dcr->StartBlock = dev->block_num;
-- dcr->StartFile = dev->file;
-- } else {
-- dcr->StartBlock = (uint32_t)dev->file_addr;
-- dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
-- }
-- /* Reset indicies */
-- dcr->VolFirstIndex = 0;
-- dcr->VolLastIndex = 0;
-+ set_new_file_parameters(dcr);
- jcr->NumWriteVolumes++;
-- dcr->NewVol = false;
-- dcr->WroteVol = false;
- }
-
- /*
-@@ -235,16 +235,8 @@
- */
- void set_new_file_parameters(DCR *dcr)
- {
-- DEVICE *dev = dcr->dev;
-+ set_start_vol_position(dcr);
-
-- /* Set new start/end positions */
-- if (dev->is_tape()) {
-- dcr->StartBlock = dev->block_num;
-- dcr->StartFile = dev->file;
-- } else {
-- dcr->StartBlock = (uint32_t)dev->file_addr;
-- dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
-- }
- /* Reset indicies */
- dcr->VolFirstIndex = 0;
- dcr->VolLastIndex = 0;
-Index: src/stored/mac.c
-===================================================================
---- src/stored/mac.c (revision 6391)
-+++ src/stored/mac.c (working copy)
-@@ -1,15 +1,7 @@
- /*
-- * SD -- mac.c -- responsible for doing
-- * migration, archive, and copy jobs.
-- *
-- * Kern Sibbald, January MMVI
-- *
-- * Version $Id$
-- */
--/*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2006-2006 Free Software Foundation Europe e.V.
-+ Copyright (C) 2006-2008 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.
-@@ -33,6 +25,14 @@
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
- */
-+/*
-+ * SD -- mac.c -- responsible for doing
-+ * migration, archive, and copy jobs.
-+ *
-+ * Kern Sibbald, January MMVI
-+ *
-+ * Version $Id$
-+ */
-
- #include "bacula.h"
- #include "stored.h"
-@@ -108,6 +108,7 @@
-
- jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
- jcr->run_time = time(NULL);
-+ set_start_vol_position(jcr->dcr);
-
- ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
- goto ok_out;
-Index: src/stored/protos.h
-===================================================================
---- src/stored/protos.h (revision 6391)
-+++ src/stored/protos.h (working copy)
-@@ -126,6 +126,7 @@
- bool open_device(DCR *dcr);
- bool first_open_device(DCR *dcr);
- bool fixup_device_block_write_error(DCR *dcr);
-+void set_start_vol_position(DCR *dcr);
- void set_new_volume_parameters(DCR *dcr);
- void set_new_file_parameters(DCR *dcr);
- bool is_device_unmounted(DEVICE *dev);
+++ /dev/null
-
- This patch should fix bug #1047 -- heap corruption when using
- strippath on certain directories.
-
- Apply it to 2.2.8 (probably prior versions) with:
-
- cd <bacula-source>
- patch -p0 <2.2.8-strip-path.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/filed/backup.c
-===================================================================
---- src/filed/backup.c (revision 6390)
-+++ src/filed/backup.c (revision 6391)
-@@ -1146,20 +1146,21 @@
- /*
- * Strip path. If it doesn't succeed put it back. If
- * it does, and there is a different link string,
-- * attempt to strip the link. If it fails, but them
-+ * attempt to strip the link. If it fails, back them
- * both back.
-+ * Don't strip symlinks.
- * I.e. if either stripping fails don't strip anything.
- */
- if (do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
-- if (ff_pkt->fname != ff_pkt->link) {
-+ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
- pm_strcpy(ff_pkt->link_save, ff_pkt->link);
- if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
-- strcpy(ff_pkt->link, ff_pkt->link_save);
-- strcpy(ff_pkt->fname, ff_pkt->fname_save);
-+ pm_strcpy(ff_pkt->link, ff_pkt->link_save);
-+ pm_strcpy(ff_pkt->fname, ff_pkt->fname_save);
- }
- }
- } else {
-- strcpy(ff_pkt->fname, ff_pkt->fname_save);
-+ pm_strcpy(ff_pkt->fname, ff_pkt->fname_save);
- }
- Dmsg2(200, "fname=%s stripped=%s\n", ff_pkt->fname_save, ff_pkt->fname);
- }
-@@ -1169,8 +1170,8 @@
- if (!(ff_pkt->flags & FO_STRIPPATH) || ff_pkt->strip_path <= 0) {
- return;
- }
-- strcpy(ff_pkt->fname, ff_pkt->fname_save);
-- if (ff_pkt->fname != ff_pkt->link) {
-- strcpy(ff_pkt->link, ff_pkt->link_save);
-+ pm_strcpy(ff_pkt->fname, ff_pkt->fname_save);
-+ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
-+ pm_strcpy(ff_pkt->link, ff_pkt->link_save);
- }
- }
+++ /dev/null
-
- This patch fixes the strippath bug that created a buffer overrun and thus
- a crash in the FD. It fixes bug #1078.
-
- Apply it to version 2.2.8 or higher with:
-
- cd <bacula-source>
- patch -p0 <2.2.8-strippath.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/filed/backup.c
-===================================================================
---- src/filed/backup.c (revision 6843)
-+++ src/filed/backup.c (working copy)
-@@ -1102,9 +1102,9 @@
-
- /* Copy to first path separator -- Win32 might have c: ... */
- while (*in && !IsPathSeparator(*in)) {
-- *out++ = *in++;
-+ out++; in++;
- }
-- *out++ = *in++;
-+ out++; in++;
- numsep++; /* one separator seen */
- for (stripped=0; stripped<count && *in; stripped++) {
- while (*in && !IsPathSeparator(*in)) {
-@@ -1129,7 +1129,11 @@
- }
-
- /*
-- * If requested strip leading components of the path
-+ * If requested strip leading components of the path so that we can
-+ * save file as if it came from a subdirectory. This is most useful
-+ * for dealing with snapshots, by removing the snapshot directory, or
-+ * in handling vendor migrations where files have been restored with
-+ * a vendor product into a subdirectory.
- */
- static void strip_path(FF_PKT *ff_pkt)
- {
-@@ -1142,27 +1146,35 @@
- ff_pkt->link_save = get_pool_memory(PM_FNAME);
- }
- pm_strcpy(ff_pkt->fname_save, ff_pkt->fname);
-+ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
-+ pm_strcpy(ff_pkt->link_save, ff_pkt->link);
-+ Dmsg2(500, "strcpy link_save=%d link=%d\n", strlen(ff_pkt->link_save),
-+ strlen(ff_pkt->link));
-+ sm_check(__FILE__, __LINE__, true);
-+ }
-
- /*
- * Strip path. If it doesn't succeed put it back. If
- * it does, and there is a different link string,
- * attempt to strip the link. If it fails, back them
- * both back.
-- * Don't strip symlinks.
-+ * Do not strip symlinks.
- * I.e. if either stripping fails don't strip anything.
- */
-- if (do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
-- if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
-- pm_strcpy(ff_pkt->link_save, ff_pkt->link);
-- if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
-- strcpy(ff_pkt->link, ff_pkt->link_save);
-- strcpy(ff_pkt->fname, ff_pkt->fname_save);
-- }
-+ if (!do_strip(ff_pkt->strip_path, ff_pkt->fname)) {
-+ unstrip_path(ff_pkt);
-+ goto rtn;
-+ }
-+ /* Strip links but not symlinks */
-+ if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
-+ if (!do_strip(ff_pkt->strip_path, ff_pkt->link)) {
-+ unstrip_path(ff_pkt);
- }
-- } else {
-- strcpy(ff_pkt->fname, ff_pkt->fname_save);
-- }
-- Dmsg2(200, "fname=%s stripped=%s\n", ff_pkt->fname_save, ff_pkt->fname);
-+ }
-+
-+rtn:
-+ Dmsg3(100, "fname=%s stripped=%s link=%s\n", ff_pkt->fname_save, ff_pkt->fname,
-+ ff_pkt->link);
- }
-
- static void unstrip_path(FF_PKT *ff_pkt)
-@@ -1172,6 +1184,11 @@
- }
- strcpy(ff_pkt->fname, ff_pkt->fname_save);
- if (ff_pkt->type != FT_LNK && ff_pkt->fname != ff_pkt->link) {
-+ Dmsg2(500, "strcpy link=%s link_save=%s\n", ff_pkt->link,
-+ ff_pkt->link_save);
- strcpy(ff_pkt->link, ff_pkt->link_save);
-+ Dmsg2(500, "strcpy link=%d link_save=%d\n", strlen(ff_pkt->link),
-+ strlen(ff_pkt->link_save));
-+ sm_check(__FILE__, __LINE__, true);
- }
- }
+++ /dev/null
-Index: scripts/bacula.in
-===================================================================
---- scripts/bacula.in (revision 7106)
-+++ scripts/bacula.in (working copy)
-@@ -13,22 +13,20 @@
- # easier to "steal" this code for the development
- # environment where they are different.
- #
--BACFDCFG=@sysconfdir@
--BACSDCFG=@sysconfdir@
--BACDIRCFG=@sysconfdir@
-+SCRIPTDIR=@scriptdir@
-
- case "$1" in
- start)
-- [ -x ${BACSDCFG}/bacula-ctl-sd ] && ${BACSDCFG}/bacula-ctl-sd $1 $2
-- [ -x ${BACFDCFG}/bacula-ctl-fd ] && ${BACFDCFG}/bacula-ctl-fd $1 $2
-- [ -x ${BACDIRCFG}/bacula-ctl-dir ] && ${BACDIRCFG}/bacula-ctl-dir $1 $2
-+ [ -x ${SCRIPTDIR}/bacula-ctl-sd ] && ${SCRIPTDIR}/bacula-ctl-sd $1 $2
-+ [ -x ${SCRIPTDIR}/bacula-ctl-fd ] && ${SCRIPTDIR}/bacula-ctl-fd $1 $2
-+ [ -x ${SCRIPTDIR}/bacula-ctl-dir ] && ${SCRIPTDIR}/bacula-ctl-dir $1 $2
- ;;
-
- stop)
- # Stop the FD first so that SD will fail jobs and update catalog
-- [ -x ${BACFDCFG}/bacula-ctl-fd ] && ${BACFDCFG}/bacula-ctl-fd $1 $2
-- [ -x ${BACSDCFG}/bacula-ctl-sd ] && ${BACSDCFG}/bacula-ctl-sd $1 $2
-- [ -x ${BACDIRCFG}/bacula-ctl-dir ] && ${BACDIRCFG}/bacula-ctl-dir $1 $2
-+ [ -x ${SCRIPTDIR}/bacula-ctl-fd ] && ${SCRIPTDIR}/bacula-ctl-fd $1 $2
-+ [ -x ${SCRIPTDIR}/bacula-ctl-sd ] && ${SCRIPTDIR}/bacula-ctl-sd $1 $2
-+ [ -x ${SCRIPTDIR}/bacula-ctl-dir ] && ${SCRIPTDIR}/bacula-ctl-dir $1 $2
- echo
- sleep 6
- ;;
-@@ -39,9 +37,9 @@
- ;;
-
- status)
-- [ -x ${BACSDCFG}/bacula-ctl-sd ] && ${BACSDCFG}/bacula-ctl-sd status
-- [ -x ${BACFDCFG}/bacula-ctl-fd ] && ${BACFDCFG}/bacula-ctl-fd status
-- [ -x ${BACDIRCFG}/bacula-ctl-dir ] && ${BACDIRCFG}/bacula-ctl-dir status
-+ [ -x ${SCRIPTDIR}/bacula-ctl-sd ] && ${SCRIPTDIR}/bacula-ctl-sd status
-+ [ -x ${SCRIPTDIR}/bacula-ctl-fd ] && ${SCRIPTDIR}/bacula-ctl-fd status
-+ [ -x ${SCRIPTDIR}/bacula-ctl-dir ] && ${SCRIPTDIR}/bacula-ctl-dir status
- ;;
-
- *)
+++ /dev/null
-Index: src/gnome2-console/console_conf.c
-===================================================================
---- src/gnome2-console/console_conf.c (revision 7106)
-+++ src/gnome2-console/console_conf.c (working copy)
-@@ -24,7 +24,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -82,8 +82,8 @@
- {"dirport", store_int, ITEM(dir_res.DIRport), 0, ITEM_DEFAULT, 9101},
- {"address", store_str, ITEM(dir_res.address), 0, ITEM_REQUIRED, 0},
- {"password", store_password, ITEM(dir_res.password), 0, 0, 0},
-- {"tlsenable", store_bit, ITEM(dir_res.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(dir_res.tls_require), 1, 0, 0},
-+ {"tlsenable", store_bool, ITEM(dir_res.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(dir_res.tls_require), 1, 0, 0},
- {"tlscacertificatefile", store_dir, ITEM(dir_res.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(dir_res.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(dir_res.tls_certfile), 0, 0, 0},
-@@ -95,8 +95,8 @@
- {"name", store_name, ITEM(con_res.hdr.name), 0, ITEM_REQUIRED, 0},
- {"description", store_str, ITEM(con_res.hdr.desc), 0, 0, 0},
- {"password", store_password, ITEM(con_res.password), 0, ITEM_REQUIRED, 0},
-- {"tlsenable", store_bit, ITEM(con_res.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(con_res.tls_require), 1, 0, 0},
-+ {"tlsenable", store_bool, ITEM(con_res.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(con_res.tls_require), 1, 0, 0},
- {"tlscacertificatefile", store_dir, ITEM(con_res.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(con_res.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(con_res.tls_certfile), 0, 0, 0},
-Index: src/gnome2-console/console_conf.h
-===================================================================
---- src/gnome2-console/console_conf.h (revision 7106)
-+++ src/gnome2-console/console_conf.h (working copy)
-@@ -8,7 +8,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
-+ Copyright (C) 2002-2008 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.
-@@ -66,8 +66,8 @@
- int DIRport; /* UA server port */
- char *address; /* UA server address */
- char *password; /* UA server password */
-- int tls_enable; /* Enable TLS */
-- int tls_require; /* Require TLS */
-+ bool tls_enable; /* Enable TLS */
-+ bool tls_require; /* Require TLS */
- char *tls_ca_certfile; /* TLS CA Certificate File */
- char *tls_ca_certdir; /* TLS CA Certificate Directory */
- char *tls_certfile; /* TLS Client Certificate File */
-@@ -84,8 +84,8 @@
- struct CONRES {
- RES hdr;
- char *password; /* UA server password */
-- int tls_enable; /* Enable TLS on all connections */
-- int tls_require; /* Require TLS on all connections */
-+ bool tls_enable; /* Enable TLS on all connections */
-+ bool tls_require; /* Require TLS on all connections */
- char *tls_ca_certfile; /* TLS CA Certificate File */
- char *tls_ca_certdir; /* TLS CA Certificate Directory */
- char *tls_certfile; /* TLS Client Certificate File */
-Index: src/wx-console/console_conf.c
-===================================================================
---- src/wx-console/console_conf.c (revision 7106)
-+++ src/wx-console/console_conf.c (working copy)
-@@ -100,12 +100,12 @@
- {"rcfile", store_dir, ITEM(res_cons.rc_file), 0, 0, 0},
- {"historyfile", store_dir, ITEM(res_cons.hist_file), 0, 0, 0},
- {"password", store_password, ITEM(res_cons.password), 0, ITEM_REQUIRED, 0},
-- {"tlsenable", store_bit, ITEM(res_cons.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(res_cons.tls_require), 1, 0, 0},
- {"tlscacertificatefile", store_dir, ITEM(res_cons.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(res_cons.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(res_cons.tls_certfile), 0, 0, 0},
- {"tlskey", store_dir, ITEM(res_cons.tls_keyfile), 0, 0, 0},
-+ {"tlsenable", store_bool, ITEM(res_cons.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(res_cons.tls_require), 1, 0, 0},
- {NULL, NULL, {0}, 0, 0, 0}
- };
-
-@@ -117,12 +117,12 @@
- {"dirport", store_int, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101},
- {"address", store_str, ITEM(res_dir.address), 0, 0, 0},
- {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0},
-- {"tlsenable", store_bit, ITEM(res_dir.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(res_dir.tls_require), 1, 0, 0},
- {"tlscacertificatefile", store_dir, ITEM(res_dir.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(res_dir.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(res_dir.tls_certfile), 0, 0, 0},
- {"tlskey", store_dir, ITEM(res_dir.tls_keyfile), 0, 0, 0},
-+ {"tlsenable", store_bool, ITEM(res_dir.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(res_dir.tls_require), 1, 0, 0},
- {NULL, NULL, {0}, 0, 0, 0}
- };
-
-Index: src/wx-console/console_conf.h
-===================================================================
---- src/wx-console/console_conf.h (revision 7106)
-+++ src/wx-console/console_conf.h (working copy)
-@@ -4,7 +4,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -63,14 +63,13 @@
- char *rc_file; /* startup file */
- char *hist_file; /* command history file */
- char *password; /* UA server password */
-- int tls_enable; /* Enable TLS on all connections */
-- int tls_require; /* Require TLS on all connections */
- char *tls_ca_certfile; /* TLS CA Certificate File */
- char *tls_ca_certdir; /* TLS CA Certificate Directory */
- char *tls_certfile; /* TLS Client Certificate File */
- char *tls_keyfile; /* TLS Client Key File */
--
- TLS_CONTEXT *tls_ctx; /* Shared TLS Context */
-+ bool tls_enable; /* Enable TLS on all connections */
-+ bool tls_require; /* Require TLS on all connections */
- };
-
- /* Director */
-@@ -79,14 +78,13 @@
- int DIRport; /* UA server port */
- char *address; /* UA server address */
- char *password; /* UA server password */
-- int tls_enable; /* Enable TLS on all connections */
-- int tls_require; /* Require TLS on all connections */
- char *tls_ca_certfile; /* TLS CA Certificate File */
- char *tls_ca_certdir; /* TLS CA Certificate Directory */
- char *tls_certfile; /* TLS Client Certificate File */
- char *tls_keyfile; /* TLS Client Key File */
--
- TLS_CONTEXT *tls_ctx; /* Shared TLS Context */
-+ bool tls_enable; /* Enable TLS on all connections */
-+ bool tls_require; /* Require TLS on all connections */
- };
-
-
-Index: src/stored/stored_conf.c
-===================================================================
---- src/stored/stored_conf.c (revision 7106)
-+++ src/stored/stored_conf.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -77,9 +77,9 @@
- {"scriptsdirectory", store_dir, ITEM(res_store.scripts_directory), 0, 0, 0},
- {"maximumconcurrentjobs", store_pint, ITEM(res_store.max_concurrent_jobs), 0, ITEM_DEFAULT, 20},
- {"heartbeatinterval", store_time, ITEM(res_store.heartbeat_interval), 0, ITEM_DEFAULT, 0},
-- {"tlsenable", store_bit, ITEM(res_store.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(res_store.tls_require), 1, 0, 0},
-- {"tlsverifypeer", store_bit, ITEM(res_store.tls_verify_peer), 1, ITEM_DEFAULT, 1},
-+ {"tlsenable", store_bool, ITEM(res_store.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(res_store.tls_require), 1, 0, 0},
-+ {"tlsverifypeer", store_bool, ITEM(res_store.tls_verify_peer), 1, ITEM_DEFAULT, 1},
- {"tlscacertificatefile", store_dir, ITEM(res_store.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(res_store.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(res_store.tls_certfile), 0, 0, 0},
-@@ -96,10 +96,10 @@
- {"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0},
- {"description", store_str, ITEM(res_dir.hdr.desc), 0, 0, 0},
- {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0},
-- {"monitor", store_bit, ITEM(res_dir.monitor), 1, ITEM_DEFAULT, 0},
-- {"tlsenable", store_bit, ITEM(res_dir.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(res_dir.tls_require), 1, 0, 0},
-- {"tlsverifypeer", store_bit, ITEM(res_dir.tls_verify_peer), 1, ITEM_DEFAULT, 1},
-+ {"monitor", store_bool, ITEM(res_dir.monitor), 1, ITEM_DEFAULT, 0},
-+ {"tlsenable", store_bool, ITEM(res_dir.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(res_dir.tls_require), 1, 0, 0},
-+ {"tlsverifypeer", store_bool, ITEM(res_dir.tls_verify_peer), 1, ITEM_DEFAULT, 1},
- {"tlscacertificatefile", store_dir, ITEM(res_dir.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(res_dir.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(res_dir.tls_certfile), 0, 0, 0},
-@@ -137,7 +137,7 @@
- {"checklabels", store_bit, ITEM(res_dev.cap_bits), CAP_CHECKLABELS, ITEM_DEFAULT, 0},
- {"requiresmount", store_bit, ITEM(res_dev.cap_bits), CAP_REQMOUNT, ITEM_DEFAULT, 0},
- {"offlineonunmount", store_bit, ITEM(res_dev.cap_bits), CAP_OFFLINEUNMOUNT, ITEM_DEFAULT, 0},
-- {"autoselect", store_bit, ITEM(res_dev.autoselect), 1, ITEM_DEFAULT, 1},
-+ {"autoselect", store_bool, ITEM(res_dev.autoselect), 1, ITEM_DEFAULT, 1},
- {"changerdevice", store_strname,ITEM(res_dev.changer_name), 0, 0, 0},
- {"changercommand", store_strname,ITEM(res_dev.changer_command), 0, 0, 0},
- {"alertcommand", store_strname,ITEM(res_dev.alert_command), 0, 0, 0},
-@@ -177,9 +177,6 @@
- };
-
-
--// {"mountanonymousvolumes", store_bit, ITEM(res_dev.cap_bits), CAP_ANONVOLS, ITEM_DEFAULT, 0},
--
--
- /* Message resource */
- extern RES_ITEM msgs_items[];
-
-Index: src/stored/stored_conf.h
-===================================================================
---- src/stored/stored_conf.h (revision 7106)
-+++ src/stored/stored_conf.h (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -126,9 +126,9 @@
- char *spool_directory; /* Spool file directory */
- int dev_type; /* device type */
- int label_type; /* label type */
-- int autoselect; /* Automatically select from AutoChanger */
-+ bool autoselect; /* Automatically select from AutoChanger */
- uint32_t drive_index; /* Autochanger drive index */
-- uint32_t cap_bits; /* Capabilities of this device */
-+ int cap_bits; /* Capabilities of this device */
- utime_t max_changer_wait; /* Changer timeout */
- utime_t max_rewind_wait; /* maximum secs to wait for rewind */
- utime_t max_open_wait; /* maximum secs to wait for open */
-Index: src/console/console_conf.c
-===================================================================
---- src/console/console_conf.c (revision 7106)
-+++ src/console/console_conf.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -88,8 +88,8 @@
- {"rcfile", store_dir, ITEM(res_cons.rc_file), 0, 0, 0},
- {"historyfile", store_dir, ITEM(res_cons.hist_file), 0, 0, 0},
- {"password", store_password, ITEM(res_cons.password), 0, ITEM_REQUIRED, 0},
-- {"tlsenable", store_bit, ITEM(res_cons.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(res_cons.tls_require), 1, 0, 0},
-+ {"tlsenable", store_bool, ITEM(res_cons.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(res_cons.tls_require), 1, 0, 0},
- {"tlscacertificatefile", store_dir, ITEM(res_cons.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(res_cons.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(res_cons.tls_certfile), 0, 0, 0},
-@@ -107,8 +107,8 @@
- {"dirport", store_int, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101},
- {"address", store_str, ITEM(res_dir.address), 0, 0, 0},
- {"password", store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0},
-- {"tlsenable", store_bit, ITEM(res_dir.tls_enable), 1, 0, 0},
-- {"tlsrequire", store_bit, ITEM(res_dir.tls_require), 1, 0, 0},
-+ {"tlsenable", store_bool, ITEM(res_dir.tls_enable), 1, 0, 0},
-+ {"tlsrequire", store_bool, ITEM(res_dir.tls_require), 1, 0, 0},
- {"tlscacertificatefile", store_dir, ITEM(res_dir.tls_ca_certfile), 0, 0, 0},
- {"tlscacertificatedir", store_dir, ITEM(res_dir.tls_ca_certdir), 0, 0, 0},
- {"tlscertificate", store_dir, ITEM(res_dir.tls_certfile), 0, 0, 0},
-Index: src/console/console_conf.h
-===================================================================
---- src/console/console_conf.h (revision 7106)
-+++ src/console/console_conf.h (working copy)
-@@ -64,16 +64,15 @@
- char *rc_file; /* startup file */
- char *hist_file; /* command history file */
- char *password; /* UA server password */
-- int tls_enable; /* Enable TLS on all connections */
-- int tls_require; /* Require TLS on all connections */
- char *tls_ca_certfile; /* TLS CA Certificate File */
- char *tls_ca_certdir; /* TLS CA Certificate Directory */
- char *tls_certfile; /* TLS Client Certificate File */
- char *tls_keyfile; /* TLS Client Key File */
- char *director; /* bind to director */
- utime_t heartbeat_interval; /* Interval to send heartbeats to Dir */
--
- TLS_CONTEXT *tls_ctx; /* Shared TLS Context */
-+ bool tls_enable; /* Enable TLS on all connections */
-+ bool tls_require; /* Require TLS on all connections */
- };
-
- /* Director */
-@@ -82,15 +81,14 @@
- int DIRport; /* UA server port */
- char *address; /* UA server address */
- char *password; /* UA server password */
-- int tls_enable; /* Enable TLS */
-- int tls_require; /* Require TLS */
- char *tls_ca_certfile; /* TLS CA Certificate File */
- char *tls_ca_certdir; /* TLS CA Certificate Directory */
- char *tls_certfile; /* TLS Client Certificate File */
- char *tls_keyfile; /* TLS Client Key File */
- utime_t heartbeat_interval; /* Interval to send heartbeats to Dir */
--
- TLS_CONTEXT *tls_ctx; /* Shared TLS Context */
-+ bool tls_enable; /* Enable TLS */
-+ bool tls_require; /* Require TLS */
- };
-
-
-Index: src/tray-monitor/tray_conf.c
-===================================================================
---- src/tray-monitor/tray_conf.c (revision 7106)
-+++ src/tray-monitor/tray_conf.c (working copy)
-@@ -82,7 +82,7 @@
- static RES_ITEM mon_items[] = {
- {"name", store_name, ITEM(res_monitor.hdr.name), 0, ITEM_REQUIRED, 0},
- {"description", store_str, ITEM(res_monitor.hdr.desc), 0, 0, 0},
-- {"requiressl", store_bit, ITEM(res_monitor.require_ssl), 1, ITEM_DEFAULT, 0},
-+ {"requiressl", store_bool, ITEM(res_monitor.require_ssl), 1, ITEM_DEFAULT, 0},
- {"password", store_password, ITEM(res_monitor.password), 0, ITEM_REQUIRED, 0},
- {"refreshinterval", store_time,ITEM(res_monitor.RefreshInterval), 0, ITEM_DEFAULT, 5},
- {"fdconnecttimeout", store_time,ITEM(res_monitor.FDConnectTimeout), 0, ITEM_DEFAULT, 60 * 30},
-@@ -96,7 +96,7 @@
- {"description", store_str, ITEM(res_dir.hdr.desc), 0, 0, 0},
- {"dirport", store_int, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101},
- {"address", store_str, ITEM(res_dir.address), 0, 0, 0},
-- {"enablessl", store_bit, ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0},
-+ {"enablessl", store_bool, ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0},
- {NULL, NULL, {0}, 0, 0, 0}
- };
-
-@@ -112,7 +112,7 @@
- {"address", store_str, ITEM(res_client.address), 0, ITEM_REQUIRED, 0},
- {"fdport", store_pint, ITEM(res_client.FDport), 0, ITEM_DEFAULT, 9102},
- {"password", store_password, ITEM(res_client.password), 0, ITEM_REQUIRED, 0},
-- {"enablessl", store_bit, ITEM(res_client.enable_ssl), 1, ITEM_DEFAULT, 0},
-+ {"enablessl", store_bool, ITEM(res_client.enable_ssl), 1, ITEM_DEFAULT, 0},
- {NULL, NULL, {0}, 0, 0, 0}
- };
-
-@@ -128,7 +128,7 @@
- {"sdaddress", store_str, ITEM(res_store.address), 0, 0, 0},
- {"password", store_password, ITEM(res_store.password), 0, ITEM_REQUIRED, 0},
- {"sdpassword", store_password, ITEM(res_store.password), 0, 0, 0},
-- {"enablessl", store_bit, ITEM(res_store.enable_ssl), 1, ITEM_DEFAULT, 0},
-+ {"enablessl", store_bool, ITEM(res_store.enable_ssl), 1, ITEM_DEFAULT, 0},
- {NULL, NULL, {0}, 0, 0, 0}
- };
-
-Index: src/tray-monitor/tray_conf.h
-===================================================================
---- src/tray-monitor/tray_conf.h (revision 7106)
-+++ src/tray-monitor/tray_conf.h (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2004-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2004-2008 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.
-@@ -67,7 +67,7 @@
- RES hdr;
- int DIRport; /* UA server port */
- char *address; /* UA server address */
-- int enable_ssl; /* Use SSL */
-+ bool enable_ssl; /* Use SSL */
- };
-
- /*
-@@ -95,7 +95,7 @@
- int FDport; /* Where File daemon listens */
- char *address;
- char *password;
-- int enable_ssl; /* Use SSL */
-+ bool enable_ssl; /* Use SSL */
- };
-
- /*
-@@ -108,7 +108,7 @@
- int SDport; /* port where Directors connect */
- char *address;
- char *password;
-- int enable_ssl; /* Use SSL */
-+ bool enable_ssl; /* Use SSL */
- };
-
- struct CONFONTRES {
+++ /dev/null
-
- This patch should fix (not tested) the recycling bug #1106 when using
- two autochangers. There is a much smaller chance that it also fixes
- bug #1103 where a volume is recycled when it is full.
-
- Apply the patch to version 2.4.0 with:
-
- cd <bacula-source>
- patch -p0 <2.4.0-recycle.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/autoprune.c
-===================================================================
---- src/dird/autoprune.c (revision 7178)
-+++ src/dird/autoprune.c (working copy)
-@@ -96,7 +96,7 @@
- POOL_MEM query(PM_MESSAGE);
- UAContext *ua;
- bool ok = false;
-- char ed1[50], ed2[100];
-+ char ed1[50], ed2[100], ed3[50];
- POOL_DBR spr;
-
- Dmsg1(050, "Prune volumes PoolId=%d\n", jcr->jr.PoolId);
-@@ -138,10 +138,18 @@
- * RecyclePoolId is the current pool or the scratch pool
- */
- const char *select = "SELECT DISTINCT MediaId,LastWritten FROM Media WHERE "
-- "(PoolId=%s OR RecyclePoolId IN (%s)) AND MediaType='%s' "
-+ "(PoolId=%s OR RecyclePoolId IN (%s)) AND MediaType='%s' %s"
- "ORDER BY LastWritten ASC,MediaId";
-
-- Mmsg(query, select, ed1, ed2, mr->MediaType);
-+ if (InChanger) {
-+ char changer[100];
-+ /* Ensure it is in this autochanger */
-+ bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s ",
-+ edit_int64(mr->StorageId, ed3));
-+ Mmsg(query, select, ed1, ed2, mr->MediaType, changer);
-+ } else {
-+ Mmsg(query, select, ed1, ed2, mr->MediaType, "");
-+ }
-
- Dmsg1(050, "query=%s\n", query.c_str());
- if (!db_get_query_dbids(ua->jcr, ua->db, query, ids)) {
-Index: src/dird/recycle.c
-===================================================================
---- src/dird/recycle.c (revision 7178)
-+++ src/dird/recycle.c (working copy)
-@@ -83,12 +83,19 @@
- const char *select =
- "SELECT MediaId,LastWritten FROM Media "
- "WHERE PoolId=%s AND Recycle=1 AND VolStatus='Purged' "
-- "AND Enabled=1 AND MediaType='%s' "
-+ "AND Enabled=1 AND MediaType='%s' %s"
- "ORDER BY LastWritten ASC,MediaId LIMIT 1";
-
- Dmsg0(100, "Enter recycle_oldest_purged_volume\n");
- oldest.MediaId = 0;
-- Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType);
-+ if (InChanger) {
-+ char changer[100];
-+ bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s ",
-+ edit_int64(mr->StorageId, ed1));
-+ Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType, changer);
-+ } else {
-+ Mmsg(query, select, edit_int64(mr->PoolId, ed1), mr->MediaType, "");
-+ }
-
- if (!db_sql_query(jcr->db, query, oldest_handler, (void *)&oldest)) {
- Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
+++ /dev/null
-
- This patch should fix bug #1094 where jobs that wrote bytes and are rescheduled
- do not keep any Pool overrides that were specified in the Schedule Run
- directives. The patch also simplifies the resource lock inc/dec.
-
- Apply it to 2.4.0 with:
-
- cd <bacula-source>
- patch -p0 <2.4.0-reschedule.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/dird/jobq.c
-===================================================================
---- src/dird/jobq.c (revision 7178)
-+++ src/dird/jobq.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2003-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2003-2008 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.
-@@ -56,9 +56,10 @@
-
- static int start_server(jobq_t *jq);
- static bool acquire_resources(JCR *jcr);
-+static bool reschedule_job(JCR *jcr, jobq_t *jq, jobq_item_t *je);
-+static void dec_read_store(JCR *jcr);
-+static void dec_write_store(JCR *jcr);
-
--
--
- /*
- * Initialize a job queue
- *
-@@ -357,8 +358,8 @@
- pthread_t id;
-
- /*
-- * if any threads are idle, wake one --
-- * actually we do a broadcast because on /lib/tls
-+ * if any threads are idle, wake one.
-+ * Actually we do a broadcast because on /lib/tls
- * these signals seem to get lost from time to time.
- */
- if (jq->idle_workers > 0) {
-@@ -477,87 +478,17 @@
- * put into the ready queue.
- */
- if (jcr->acquired_resource_locks) {
-- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-- }
-- if (jcr->wstore) {
-- jcr->wstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- }
-+ dec_read_store(jcr);
-+ dec_write_store(jcr);
- jcr->client->NumConcurrentJobs--;
- jcr->job->NumConcurrentJobs--;
- jcr->acquired_resource_locks = false;
- }
-
-- /*
-- * Reschedule the job if necessary and requested
-- */
-- if (jcr->job->RescheduleOnError &&
-- jcr->JobStatus != JS_Terminated &&
-- jcr->JobStatus != JS_Canceled &&
-- jcr->JobType == JT_BACKUP &&
-- (jcr->job->RescheduleTimes == 0 ||
-- jcr->reschedule_count < jcr->job->RescheduleTimes)) {
-- char dt[50], dt2[50];
-+ if (reschedule_job(jcr, jq, je)) {
-+ continue; /* go look for more work */
-+ }
-
-- /*
-- * Reschedule this job by cleaning it up, but
-- * reuse the same JobId if possible.
-- */
-- time_t now = time(NULL);
-- jcr->reschedule_count++;
-- jcr->sched_time = now + jcr->job->RescheduleInterval;
-- bstrftime(dt, sizeof(dt), now);
-- bstrftime(dt2, sizeof(dt2), jcr->sched_time);
-- Dmsg4(2300, "Rescheduled Job %s to re-run in %d seconds.(now=%u,then=%u)\n", jcr->Job,
-- (int)jcr->job->RescheduleInterval, now, jcr->sched_time);
-- Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds (%s).\n"),
-- jcr->Job, dt, (int)jcr->job->RescheduleInterval, dt2);
-- dird_free_jcr_pointers(jcr); /* partial cleanup old stuff */
-- jcr->JobStatus = -1;
-- set_jcr_job_status(jcr, JS_WaitStartTime);
-- jcr->SDJobStatus = 0;
-- if (jcr->JobBytes == 0) {
-- Dmsg2(2300, "Requeue job=%d use=%d\n", jcr->JobId, jcr->use_count());
-- V(jq->mutex);
-- jobq_add(jq, jcr); /* queue the job to run again */
-- P(jq->mutex);
-- free_jcr(jcr); /* release jcr */
-- free(je); /* free the job entry */
-- continue; /* look for another job to run */
-- }
-- /*
-- * Something was actually backed up, so we cannot reuse
-- * the old JobId or there will be database record
-- * conflicts. We now create a new job, copying the
-- * appropriate fields.
-- */
-- JCR *njcr = new_jcr(sizeof(JCR), dird_free_jcr);
-- set_jcr_defaults(njcr, jcr->job);
-- njcr->reschedule_count = jcr->reschedule_count;
-- njcr->sched_time = jcr->sched_time;
-- njcr->JobLevel = jcr->JobLevel;
-- njcr->JobStatus = -1;
-- set_jcr_job_status(njcr, jcr->JobStatus);
-- if (jcr->rstore) {
-- copy_rstorage(njcr, jcr->rstorage, _("previous Job"));
-- } else {
-- free_rstorage(njcr);
-- }
-- if (jcr->wstore) {
-- copy_wstorage(njcr, jcr->wstorage, _("previous Job"));
-- } else {
-- free_wstorage(njcr);
-- }
-- njcr->messages = jcr->messages;
-- Dmsg0(2300, "Call to run new job\n");
-- V(jq->mutex);
-- run_job(njcr); /* This creates a "new" job */
-- free_jcr(njcr); /* release "new" jcr */
-- P(jq->mutex);
-- Dmsg0(2300, "Back from running new job.\n");
-- }
- /* Clean up and release old jcr */
- Dmsg2(2300, "====== Termination job=%d use_cnt=%d\n", jcr->JobId, jcr->use_count());
- jcr->SDJobStatus = 0;
-@@ -671,6 +602,91 @@
- }
-
- /*
-+ * Returns true if cleanup done and we should look for more work
-+ */
-+static bool reschedule_job(JCR *jcr, jobq_t *jq, jobq_item_t *je)
-+{
-+ /*
-+ * Reschedule the job if necessary and requested
-+ */
-+ if (jcr->job->RescheduleOnError &&
-+ jcr->JobStatus != JS_Terminated &&
-+ jcr->JobStatus != JS_Canceled &&
-+ jcr->JobType == JT_BACKUP &&
-+ (jcr->job->RescheduleTimes == 0 ||
-+ jcr->reschedule_count < jcr->job->RescheduleTimes)) {
-+ char dt[50], dt2[50];
-+
-+ /*
-+ * Reschedule this job by cleaning it up, but
-+ * reuse the same JobId if possible.
-+ */
-+ time_t now = time(NULL);
-+ jcr->reschedule_count++;
-+ jcr->sched_time = now + jcr->job->RescheduleInterval;
-+ bstrftime(dt, sizeof(dt), now);
-+ bstrftime(dt2, sizeof(dt2), jcr->sched_time);
-+ Dmsg4(2300, "Rescheduled Job %s to re-run in %d seconds.(now=%u,then=%u)\n", jcr->Job,
-+ (int)jcr->job->RescheduleInterval, now, jcr->sched_time);
-+ Jmsg(jcr, M_INFO, 0, _("Rescheduled Job %s at %s to re-run in %d seconds (%s).\n"),
-+ jcr->Job, dt, (int)jcr->job->RescheduleInterval, dt2);
-+ dird_free_jcr_pointers(jcr); /* partial cleanup old stuff */
-+ jcr->JobStatus = -1;
-+ set_jcr_job_status(jcr, JS_WaitStartTime);
-+ jcr->SDJobStatus = 0;
-+ if (jcr->JobBytes == 0) {
-+ Dmsg2(2300, "Requeue job=%d use=%d\n", jcr->JobId, jcr->use_count());
-+ V(jq->mutex);
-+ jobq_add(jq, jcr); /* queue the job to run again */
-+ P(jq->mutex);
-+ free_jcr(jcr); /* release jcr */
-+ free(je); /* free the job entry */
-+ return true; /* we already cleaned up */
-+ }
-+ /*
-+ * Something was actually backed up, so we cannot reuse
-+ * the old JobId or there will be database record
-+ * conflicts. We now create a new job, copying the
-+ * appropriate fields.
-+ */
-+ JCR *njcr = new_jcr(sizeof(JCR), dird_free_jcr);
-+ set_jcr_defaults(njcr, jcr->job);
-+ njcr->reschedule_count = jcr->reschedule_count;
-+ njcr->sched_time = jcr->sched_time;
-+ njcr->JobLevel = jcr->JobLevel;
-+ njcr->pool = jcr->pool;
-+ njcr->run_pool_override = jcr->run_pool_override;
-+ njcr->full_pool = jcr->full_pool;
-+ njcr->run_full_pool_override = jcr->run_full_pool_override;
-+ njcr->inc_pool = jcr->inc_pool;
-+ njcr->run_inc_pool_override = jcr->run_inc_pool_override;
-+ njcr->diff_pool = jcr->diff_pool;
-+ njcr->JobStatus = -1;
-+ set_jcr_job_status(njcr, jcr->JobStatus);
-+ if (jcr->rstore) {
-+ copy_rstorage(njcr, jcr->rstorage, _("previous Job"));
-+ } else {
-+ free_rstorage(njcr);
-+ }
-+ if (jcr->wstore) {
-+ copy_wstorage(njcr, jcr->wstorage, _("previous Job"));
-+ } else {
-+ free_wstorage(njcr);
-+ }
-+ njcr->messages = jcr->messages;
-+ njcr->spool_data = jcr->spool_data;
-+ njcr->write_part_after_job = jcr->write_part_after_job;
-+ Dmsg0(2300, "Call to run new job\n");
-+ V(jq->mutex);
-+ run_job(njcr); /* This creates a "new" job */
-+ free_jcr(njcr); /* release "new" jcr */
-+ P(jq->mutex);
-+ Dmsg0(2300, "Back from running new job.\n");
-+ }
-+ return false;
-+}
-+
-+/*
- * See if we can acquire all the necessary resources for the job (JCR)
- *
- * Returns: true if successful
-@@ -681,11 +697,19 @@
- bool skip_this_jcr = false;
-
- jcr->acquired_resource_locks = false;
-+ if (jcr->rstore == jcr->wstore) { /* deadlock */
-+ Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
-+ " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"),
-+ jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
-+ set_jcr_job_status(jcr, JS_Canceled);
-+ return false;
-+ }
- if (jcr->rstore) {
- Dmsg1(200, "Rstore=%s\n", jcr->rstore->name());
- if (jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs) {
-+// jcr->rstore->NumConcurrentReadJobs++;
- jcr->rstore->NumConcurrentJobs++;
-- Dmsg0(200, "Set rncj=1\n");
-+ Dmsg1(200, "Inc rncj=%d\n", jcr->rstore->NumConcurrentJobs);
- } else {
- Dmsg1(200, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs);
- set_jcr_job_status(jcr, JS_WaitStoreRes);
-@@ -695,25 +719,11 @@
-
- if (jcr->wstore) {
- Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
-- if (jcr->rstore == jcr->wstore) { /* deadlock */
-- jcr->rstore->NumConcurrentJobs--; /* back out rstore */
-- Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
-- " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"),
-- jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
-- set_jcr_job_status(jcr, JS_Canceled);
-- return false;
-- }
-- if (jcr->wstore->NumConcurrentJobs == 0 &&
-- jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
-- /* Simple case, first job */
-- jcr->wstore->NumConcurrentJobs = 1;
-- Dmsg0(200, "Set wncj=1\n");
-- } else if (jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
-+ if (jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
- jcr->wstore->NumConcurrentJobs++;
- Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
- } else if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs--; /* back out rstore */
-- Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+ dec_read_store(jcr);
- skip_this_jcr = true;
- } else {
- Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-@@ -729,14 +739,8 @@
- jcr->client->NumConcurrentJobs++;
- } else {
- /* Back out previous locks */
-- if (jcr->wstore) {
-- jcr->wstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- }
-- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-- }
-+ dec_write_store(jcr);
-+ dec_read_store(jcr);
- set_jcr_job_status(jcr, JS_WaitClientRes);
- return false;
- }
-@@ -744,14 +748,8 @@
- jcr->job->NumConcurrentJobs++;
- } else {
- /* Back out previous locks */
-- if (jcr->wstore) {
-- jcr->wstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- }
-- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-- }
-+ dec_write_store(jcr);
-+ dec_read_store(jcr);
- jcr->client->NumConcurrentJobs--;
- set_jcr_job_status(jcr, JS_WaitJobRes);
- return false;
-@@ -760,3 +758,23 @@
- jcr->acquired_resource_locks = true;
- return true;
- }
-+
-+static void dec_read_store(JCR *jcr)
-+{
-+ if (jcr->rstore) {
-+// jcr->rstore->NumConcurrentReadJobs--; /* back out rstore */
-+ jcr->rstore->NumConcurrentJobs--; /* back out rstore */
-+ Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-+// ASSERT(jcr->rstore->NumConcurrentReadJobs >= 0);
-+ ASSERT(jcr->rstore->NumConcurrentJobs >= 0);
-+ }
-+}
-+
-+static void dec_write_store(JCR *jcr)
-+{
-+ if (jcr->wstore) {
-+ jcr->wstore->NumConcurrentJobs--;
-+ Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+ ASSERT(jcr->wstore->NumConcurrentJobs >= 0);
-+ }
-+}
+++ /dev/null
-
- This patch should fix a volume locking deadlock condition in the
- Storage daemon as reported in bug #1100.
-
- Apply it to version 2.4.0 with:
-
- cd <bacula-source>
- patch -p0 <2.4.0-sd-deadlock.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/stored/mount.c
-===================================================================
---- src/stored/mount.c (revision 7204)
-+++ src/stored/mount.c (working copy)
-@@ -179,9 +179,13 @@
- }
- Dmsg2(150, "Ask=%d autochanger=%d\n", ask, autochanger);
-
-- if (ask && !dir_ask_sysop_to_mount_volume(dcr, ST_APPEND)) {
-- Dmsg0(150, "Error return ask_sysop ...\n");
-- goto bail_out; /* error return */
-+ if (ask) {
-+ unlock_volumes();
-+ if (!dir_ask_sysop_to_mount_volume(dcr, ST_APPEND)) {
-+ Dmsg0(150, "Error return ask_sysop ...\n");
-+ goto no_lock_bail_out; /* error return */
-+ }
-+ lock_volumes();
- }
- if (job_canceled(jcr)) {
- goto bail_out;
+++ /dev/null
-
- This patch should fix bug #1118 where bat does not restore correctly
- if multiple pools were used. Bat actually works correctly, but the default
- Pool is taken from the Job resource, and for multiple pools the default
- should be Any. This patch makes Any the default restore pool.
- Apply it to version 2.4.1 with:
-
- cd <bacula-source>
- patch -p0 <2.4.1-bat-restore.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/qt-console/restore/prerestore.cpp
-===================================================================
---- src/qt-console/restore/prerestore.cpp (revision 7414)
-+++ src/qt-console/restore/prerestore.cpp (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2007-20087 Free Software Foundation Europe e.V.
-+ Copyright (C) 2007-2008 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.
-@@ -20,7 +20,7 @@
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-- Bacula® is a registered trademark of John Walker.
-+ Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-@@ -146,7 +146,7 @@
- cmd += " fileset=\"" + filesetCombo->currentText() + "\"";
- cmd += " client=\"" + clientCombo->currentText() + "\"";
- if (selectJobRadio->isChecked()) {
-- if (poolCombo->currentText() != "Any" ){
-+ if (poolCombo->currentText() != tr("Any") ){
- cmd += " pool=\"" + poolCombo->currentText() + "\"";
- }
- cmd += " storage=\"" + storageCombo->currentText() + "\"";
-@@ -171,12 +171,10 @@
- Pmsg1(000, "preRestore command \'%s\'\n", cmd.toUtf8().data());
- }
- m_console->write_dir(cmd.toUtf8().data());
--// consoleCommand(cmd);
-
- /* Note, do not turn notifier back on here ... */
- if (selectFilesRadio->isChecked()) {
- setConsoleCurrent();
--// new restorePage();
- closeStackPage();
- } else {
- closeStackPage();
-@@ -210,7 +208,7 @@
- if (m_console->get_job_defaults(job_defs)) {
- filesetCombo->setCurrentIndex(filesetCombo->findText(job_defs.fileset_name, Qt::MatchExactly));
- clientCombo->setCurrentIndex(clientCombo->findText(job_defs.client_name, Qt::MatchExactly));
-- poolCombo->setCurrentIndex(poolCombo->findText(job_defs.pool_name, Qt::MatchExactly));
-+ poolCombo->setCurrentIndex(poolCombo->findText(tr("Any"), Qt::MatchExactly));
- storageCombo->setCurrentIndex(storageCombo->findText(job_defs.store_name, Qt::MatchExactly));
- }
- }
+++ /dev/null
-
- This patch should help prevent jobs from being migrated twice if
- you happen to run two migration jobs at the same time. This should
- fix or improve the problem reported in bug #1129.
- Apply it to version 2.4.1 with:
-
- cd <bacula-source>
- patch -p0 <2.4.1-migration.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 7433)
-+++ src/dird/migrate.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2004-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2004-2008 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.
-@@ -274,6 +274,21 @@
- return true;
- }
-
-+ if (!db_get_job_record(jcr, jcr->db, &jcr->previous_jr)) {
-+ Jmsg(jcr, M_FATAL, 0, _("Could not get job record for JobId %s to migrate. ERR=%s"),
-+ edit_int64(jcr->previous_jr.JobId, ed1),
-+ db_strerror(jcr->db));
-+ set_jcr_job_status(jcr, JS_Terminated);
-+ migration_cleanup(jcr, jcr->JobStatus);
-+ return true;
-+ }
-+ /* Make sure this job was not already migrated */
-+ if (jcr->previous_jr.JobType != JT_BACKUP) {
-+ set_jcr_job_status(jcr, JS_Terminated);
-+ migration_cleanup(jcr, jcr->JobStatus);
-+ return true;
-+ }
-+
- /* Print Job Start message */
- Jmsg(jcr, M_INFO, 0, _("Start Migration JobId %s, Job=%s\n"),
- edit_uint64(jcr->JobId, ed1), jcr->Job);
+++ /dev/null
-
- This patch causes the SD to try at least once to mount a Volume
- that is not in an Autochanger before asking the operator to
- intervene. Without it, the user must issue a mount command for
- every File based volume that is needed.
-
- Apply to 2.4.1 with the following:
-
- cd <bacula-source>
- patch -p0 <2.4.1-mount.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/stored/mount.c
-===================================================================
---- src/stored/mount.c (revision 7378)
-+++ src/stored/mount.c (working copy)
-@@ -142,7 +142,7 @@
- } else {
- autochanger = false;
- VolCatInfo.Slot = 0;
-- ask = true;
-+ ask = retry >= 2;
- }
- Dmsg1(150, "autoload_dev returns %d\n", autochanger);
- /*
+++ /dev/null
-
- This patch removes an unfortunate piece of debug code that crept into
- the 2.4.1 release and causes it to purposely, but incorrectly seg fault
- whenever a volume name error occurs. Typically this may happen if a
- non-bacula tape is mounted at startup or at the end of volume during
- restore.
-
- Apply the patch with:
-
- cd <bacula-source>
- patch -p0 <2.4.1-sd-crash.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/stored/acquire.c
-===================================================================
---- src/stored/acquire.c (revision 7405)
-+++ src/stored/acquire.c (working copy)
-@@ -266,7 +266,6 @@
- dev->close();
- }
- dev->set_load();
-- ASSERT(0);
- /* Fall through */
- default:
- Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
+++ /dev/null
-
- This patch corrects a problem of manual mounting of volumes,
- where Bacula will accept an incorrect volume for restore.
- Apply it to version 2.4.1 with:
-
- cd <bacula-source>
- patch -p0 <2.4.1-wrong-volume.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/stored/mount.c
-===================================================================
---- src/stored/mount.c (revision 7422)
-+++ src/stored/mount.c (working copy)
-@@ -20,7 +20,7 @@
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-- Bacula® is a registered trademark of John Walker.
-+ Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-@@ -113,7 +113,9 @@
- ask = true; /* ask operator to mount tape */
- do_find = true; /* re-find a volume after unload */
- }
-- do_swapping(true /*writing*/);
-+ do_unload();
-+ do_swapping(true /*is_writing*/);
-+ do_load(true /*is_writing*/);
-
- if (do_find && !find_a_volume()) {
- goto no_lock_bail_out;
-@@ -500,12 +502,30 @@
- return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
- }
-
--void DCR::do_swapping(bool is_writing)
-+bool DCR::do_unload()
- {
- if (dev->must_unload()) {
- Dmsg1(100, "must_unload release %s\n", dev->print_name());
- release_volume();
- }
-+ return false;
-+}
-+
-+bool DCR::do_load(bool is_writing)
-+{
-+ if (dev->must_load()) {
-+ Dmsg1(100, "Must load %s\n", dev->print_name());
-+ if (autoload_device(this, is_writing, NULL) > 0) {
-+ dev->clear_load();
-+ return true;
-+ }
-+ return false;
-+ }
-+ return true;
-+}
-+
-+void DCR::do_swapping(bool is_writing)
-+{
- /*
- * See if we are asked to swap the Volume from another device
- * if so, unload the other device here, and attach the
-@@ -522,17 +542,12 @@
- }
- if (dev->vol) {
- dev->vol->clear_swapping();
-+ Dmsg1(100, "=== set in_use vol=%s\n", dev->vol->vol_name);
- dev->vol->set_in_use();
- dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */
- }
- dev->swap_dev = NULL;
- }
-- if (dev->must_load()) {
-- Dmsg1(100, "Must load %s\n", dev->print_name());
-- if (autoload_device(this, is_writing, NULL) > 0) {
-- dev->clear_load();
-- }
-- }
- }
-
-
-Index: src/stored/dev.h
-===================================================================
---- src/stored/dev.h (revision 7422)
-+++ src/stored/dev.h (working copy)
-@@ -542,6 +542,8 @@
- int check_volume_label(bool &ask, bool &autochanger);
- void release_volume();
- void do_swapping(bool is_writing);
-+ bool do_unload();
-+ bool do_load(bool is_writing);
- bool is_tape_position_ok();
- };
-
-Index: src/stored/acquire.c
-===================================================================
---- src/stored/acquire.c (revision 7422)
-+++ src/stored/acquire.c (working copy)
-@@ -20,7 +20,7 @@
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-- Bacula® is a registered trademark of John Walker.
-+ Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-@@ -38,6 +38,7 @@
-
- /* Forward referenced functions */
- static void attach_dcr_to_dev(DCR *dcr);
-+static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol);
-
-
- /*********************************************************************
-@@ -88,15 +89,9 @@
- jcr->NumReadVolumes, jcr->CurReadVolume);
- goto get_out; /* should not happen */
- }
-- /*
-- * Note, if we want to be able to work from a .bsr file only
-- * for disaster recovery, we must "simulate" reading the catalog
-- */
-- bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
-- bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
-- bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
-- dcr->VolCatInfo.Slot = vol->Slot;
-- dcr->VolCatInfo.InChanger = vol->Slot > 0;
-+ set_dcr_from_vol(dcr, vol);
-+
-+ Dmsg2(100, "Want Vol=%s Slot=%d\n", vol->VolumeName, vol->Slot);
-
- /*
- * If the MediaType requested for this volume is not the
-@@ -174,20 +169,12 @@
-
- dev->clear_unload();
-
-- if (reserve_volume(dcr, dcr->VolumeName) == NULL) {
-- Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
-- dcr->dev->print_name());
-- Jmsg2(jcr, M_FATAL, 0, _("Could not reserve volume %s on %s\n"), dcr->VolumeName,
-- dcr->dev->print_name());
-- goto get_out;
-- }
- if (dev->vol && dev->vol->is_swapping()) {
- dev->vol->set_slot(vol->Slot);
- Dmsg3(100, "swapping: slot=%d Vol=%s dev=%s\n", dev->vol->get_slot(),
- dev->vol->vol_name, dev->print_name());
- }
-
--
- init_device_wait_timers(dcr);
-
- tape_previously_mounted = dev->can_read() || dev->can_append() ||
-@@ -217,7 +204,10 @@
- goto get_out; /* error return */
- }
-
-- dcr->do_swapping(false/*is_writing*/);
-+ dcr->do_unload();
-+ dcr->do_swapping(false/*!is_writing*/);
-+ dcr->do_load(false /*!is_writing*/);
-+ set_dcr_from_vol(dcr, vol); /* refresh dcr with desired volume info */
-
- /*
- * This code ensures that the device is ready for
-@@ -239,10 +229,12 @@
- vol_label_status = read_dev_volume_label(dcr);
- switch (vol_label_status) {
- case VOL_OK:
-+ Dmsg0(50, "Got correct volume.\n");
- ok = true;
- dev->VolCatInfo = dcr->VolCatInfo; /* structure assignment */
- break; /* got it */
- case VOL_IO_ERROR:
-+ Dmsg0(50, "IO Error\n");
- /*
- * Send error message generated by read_dev_volume_label()
- * only we really had a tape mounted. This supresses superfluous
-@@ -253,13 +245,10 @@
- }
- goto default_path;
- case VOL_NAME_ERROR:
-+ Dmsg0(50, "Vol name error.\n");
- if (dev->is_volume_to_unload()) {
- goto default_path;
- }
--// if (tape_initially_mounted) {
-- tape_initially_mounted = false;
--// goto default_path;
--// }
- dev->set_unload(); /* force unload of unwanted tape */
- if (!unload_autochanger(dcr, -1)) {
- /* at least free the device so we can re-open with correct volume */
-@@ -270,6 +259,7 @@
- default:
- Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
- default_path:
-+ Dmsg0(50, "default path\n");
- tape_previously_mounted = true;
-
- /*
-@@ -289,15 +279,6 @@
- try_autochanger = false;
- continue; /* try reading volume mounted */
- }
-- /* Try closing and re-opening */
-- dev->close();
-- if (dev->open(dcr, OPEN_READ_ONLY) >= 0) {
-- continue;
-- }
-- if (!dev->poll) {
-- Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
-- dev->print_name(), dcr->VolumeName, dev->bstrerror());
-- }
- }
-
- /* Mount a specific volume and no other */
-@@ -305,7 +286,7 @@
- if (!dir_ask_sysop_to_mount_volume(dcr, ST_READ)) {
- goto get_out; /* error return */
- }
-- try_autochanger = true; /* permit using autochanger again */
-+ try_autochanger = true; /* permit trying the autochanger again */
- continue; /* try reading again */
- } /* end switch */
- break;
-@@ -693,3 +674,16 @@
- }
- free(dcr);
- }
-+
-+static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol)
-+{
-+ /*
-+ * Note, if we want to be able to work from a .bsr file only
-+ * for disaster recovery, we must "simulate" reading the catalog
-+ */
-+ bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
-+ bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
-+ bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
-+ dcr->VolCatInfo.Slot = vol->Slot;
-+ dcr->VolCatInfo.InChanger = vol->Slot > 0;
-+}
+++ /dev/null
-
- This patch should clean up two problems with bat:
- 1. Eliminate print error output concerning job plotting
- 2. Eliminate the error messages where bat complains about being busy.
- It also backports some new trunk code.
- Apply it to Bacula version 2.4.2 with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-bat.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/qt-console/mainwin.h
-===================================================================
---- src/qt-console/mainwin.h (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/mainwin.h (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -107,9 +107,7 @@
- void runButtonClicked();
- void estimateButtonClicked();
- void browseButtonClicked();
--#ifdef HAVE_QWT
- void jobPlotButtonClicked();
--#endif
- void restoreButtonClicked();
- void undockWindowButton();
- void treeItemChanged(QTreeWidgetItem *, QTreeWidgetItem *);
-Index: src/qt-console/fileset/fileset.h
-===================================================================
---- src/qt-console/fileset/fileset.h (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/fileset/fileset.h (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -62,6 +62,7 @@
- void createContextMenu();
- QString m_currentlyselected;
- bool m_populated;
-+ bool m_populating;
- bool m_checkcurwidget;
- };
-
-Index: src/qt-console/fileset/fileset.cpp
-===================================================================
---- src/qt-console/fileset/fileset.cpp (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/fileset/fileset.cpp (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -50,6 +50,7 @@
-
- /* mp_treeWidget, FileSet Tree Tree Widget inherited from ui_fileset.h */
- m_populated = false;
-+ m_populating = false;
- m_checkcurwidget = true;
- m_closeable = false;
- readSettings();
-@@ -70,6 +71,10 @@
- */
- void FileSet::populateTree()
- {
-+ if (m_populating)
-+ return;
-+ m_populating = true;
-+
- QTreeWidgetItem *filesetItem, *topItem;
-
- if (!m_console->preventInUseConnect())
-@@ -102,7 +107,7 @@
- " FROM FileSet"
- " WHERE ";
- query += " FileSet='" + filesetName + "'";
-- query += " ORDER BY FileSet";
-+ query += " ORDER BY CreateTime DESC LIMIT 1";
-
- QStringList results;
- if (mainWin->m_sqlDebug) {
-@@ -135,7 +140,7 @@
- for (int cnter=0; cnter<headerlist.size(); cnter++) {
- mp_treeWidget->resizeColumnToContents(cnter);
- }
--
-+ m_populating = false;
- }
-
- /*
-Index: src/qt-console/clients/clients.cpp
-===================================================================
---- src/qt-console/clients/clients.cpp (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/clients/clients.cpp (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -51,6 +51,7 @@
-
- /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_client.h */
- m_populated = false;
-+ m_populating = false;
- m_checkcurwidget = true;
- m_closeable = false;
- /* add context sensitive menu items specific to this classto the page
-@@ -70,6 +71,9 @@
- */
- void Clients::populateTree()
- {
-+ if (m_populating)
-+ return;
-+ m_populating = true;
- QTreeWidgetItem *clientItem, *topItem;
-
- if (!m_console->preventInUseConnect())
-@@ -135,6 +139,7 @@
- for(int cnter=0; cnter<headerlist.size(); cnter++) {
- mp_treeWidget->resizeColumnToContents(cnter);
- }
-+ m_populating = false;
- }
-
- /*
-Index: src/qt-console/clients/clients.h
-===================================================================
---- src/qt-console/clients/clients.h (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/clients/clients.h (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -62,6 +62,7 @@
- void createContextMenu();
- QString m_currentlyselected;
- bool m_populated;
-+ bool m_populating;
- bool m_checkcurwidget;
- };
-
-Index: src/qt-console/storage/storage.cpp
-===================================================================
---- src/qt-console/storage/storage.cpp (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/storage/storage.cpp (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -52,6 +52,7 @@
-
- /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_storage.h */
- m_populated = false;
-+ m_populating = false;
- m_checkcurwidget = true;
- m_closeable = false;
- m_currentStorage = "";
-@@ -71,6 +72,9 @@
- */
- void Storage::populateTree()
- {
-+ if (m_populating)
-+ return;
-+ m_populating = true;
- QTreeWidgetItem *storageItem, *topItem;
-
- if (!m_console->preventInUseConnect())
-@@ -135,6 +139,7 @@
- for(int cnter=0; cnter<headerlist.size(); cnter++) {
- mp_treeWidget->resizeColumnToContents(cnter);
- }
-+ m_populating = false;
- }
-
- /*
-Index: src/qt-console/storage/storage.h
-===================================================================
---- src/qt-console/storage/storage.h (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/storage/storage.h (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -66,6 +66,7 @@
- QString m_currentStorage;
- int m_currentAutoChanger;
- bool m_populated;
-+ bool m_populating;
- bool m_checkcurwidget;
- };
-
-Index: src/qt-console/medialist/medialist.h
-===================================================================
---- src/qt-console/medialist/medialist.h (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/medialist/medialist.h (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -66,10 +66,13 @@
- private:
- void createContextMenu();
- void setStatusColor(QTreeWidgetItem *, QString &, int &);
-+ void writeExpandedSettings();
- QString m_currentVolumeName;
- QString m_currentVolumeId;
- bool m_populated;
-+ bool m_populating;
- bool m_checkcurwidget;
-+ QTreeWidgetItem *m_topItem;
- };
-
- #endif /* _MEDIALIST_H_ */
-Index: src/qt-console/medialist/medialist.cpp
-===================================================================
---- src/qt-console/medialist/medialist.cpp (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/medialist/medialist.cpp (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -54,6 +54,7 @@
-
- /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_medialist.h */
- m_populated = false;
-+ m_populating = false;
- m_checkcurwidget = true;
- m_closeable = false;
- /* add context sensitive menu items specific to this classto the page
-@@ -64,6 +65,8 @@
-
- MediaList::~MediaList()
- {
-+ if (m_populated)
-+ writeExpandedSettings();
- }
-
- /*
-@@ -72,7 +75,10 @@
- */
- void MediaList::populateTree()
- {
-- QTreeWidgetItem *mediatreeitem, *pooltreeitem, *topItem;
-+ QTreeWidgetItem *mediatreeitem, *pooltreeitem;
-+ if (m_populating)
-+ return;
-+ m_populating = true;
-
- if (!m_console->preventInUseConnect())
- return;
-@@ -85,23 +91,31 @@
- int statusIndex = headerlist.indexOf("Status");
-
- m_checkcurwidget = false;
-+ if (m_populated)
-+ writeExpandedSettings();
- mp_treeWidget->clear();
- m_checkcurwidget = true;
- mp_treeWidget->setColumnCount(headerlist.count());
-- topItem = new QTreeWidgetItem(mp_treeWidget);
-- topItem->setText(0, "Pools");
-- topItem->setData(0, Qt::UserRole, 0);
-- topItem->setExpanded(true);
-+ m_topItem = new QTreeWidgetItem(mp_treeWidget);
-+ m_topItem->setText(0, "Pools");
-+ m_topItem->setData(0, Qt::UserRole, 0);
-+ m_topItem->setExpanded(true);
-
- mp_treeWidget->setHeaderLabels(headerlist);
-
-+ QSettings settings(m_console->m_dir->name(), "bat");
-+ settings.beginGroup("MediaListTreeExpanded");
- QString query;
-
- foreach (QString pool_listItem, m_console->pool_list) {
-- pooltreeitem = new QTreeWidgetItem(topItem);
-+ pooltreeitem = new QTreeWidgetItem(m_topItem);
- pooltreeitem->setText(0, pool_listItem);
- pooltreeitem->setData(0, Qt::UserRole, 1);
-- pooltreeitem->setExpanded(true);
-+ if(settings.contains(pool_listItem)) {
-+ pooltreeitem->setExpanded(settings.value(pool_listItem).toBool());
-+ } else {
-+ pooltreeitem->setExpanded(true);
-+ }
-
- query = "SELECT Media.VolumeName AS Media, "
- " Media.MediaId AS Id, Media.VolStatus AS VolStatus,"
-@@ -151,10 +165,12 @@
- } /* foreach resultline */
- } /* if results from query */
- } /* foreach pool_listItem */
-+ settings.endGroup();
- /* Resize the columns */
- for(int cnter=0; cnter<headerlist.count(); cnter++) {
- mp_treeWidget->resizeColumnToContents(cnter);
- }
-+ m_populating = false;
- }
-
- void MediaList::setStatusColor(QTreeWidgetItem *item, QString &field, int &index)
-@@ -362,3 +378,18 @@
- consoleCommand(cmd);
- populateTree();
- }
-+
-+/*
-+ * Write settings to save expanded states of the pools
-+ */
-+void MediaList::writeExpandedSettings()
-+{
-+ QSettings settings(m_console->m_dir->name(), "bat");
-+ settings.beginGroup("MediaListTreeExpanded");
-+ int childcount = m_topItem->childCount();
-+ for (int cnt=0; cnt<childcount; cnt++) {
-+ QTreeWidgetItem *poolitem = m_topItem->child(cnt);
-+ settings.setValue(poolitem->text(0), poolitem->isExpanded());
-+ }
-+ settings.endGroup();
-+}
-Index: src/qt-console/mainwin.cpp
-===================================================================
---- src/qt-console/mainwin.cpp (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/mainwin.cpp (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -441,14 +441,14 @@
- new prerestorePage();
- }
-
--#ifdef HAVE_QWT
- void MainWin::jobPlotButtonClicked()
- {
-+#ifdef HAVE_QWT
- JobPlotPass pass;
- pass.use = false;
- new JobPlot(NULL, pass);
-+#endif
- }
--#endif
-
- /*
- * The user just finished typing a line in the command line edit box
-Index: src/qt-console/jobs/jobs.h
-===================================================================
---- src/qt-console/jobs/jobs.h (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/jobs/jobs.h (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -66,6 +66,7 @@
- void createContextMenu();
- QString m_currentlyselected;
- bool m_populated;
-+ bool m_populating;
- bool m_checkcurwidget;
- int m_typeIndex;
- };
-Index: src/qt-console/jobs/jobs.cpp
-===================================================================
---- src/qt-console/jobs/jobs.cpp (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/jobs/jobs.cpp (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -49,6 +49,7 @@
-
- /* mp_treeWidget, Storage Tree Tree Widget inherited from ui_client.h */
- m_populated = false;
-+ m_populating = false;
- m_checkcurwidget = true;
- m_closeable = false;
- /* add context sensitive menu items specific to this classto the page
-@@ -68,6 +69,9 @@
- */
- void Jobs::populateTree()
- {
-+ if (m_populating)
-+ return;
-+ m_populating = true;
- QTreeWidgetItem *jobsItem, *topItem;
-
- if (!m_console->preventInUseConnect())
-Index: src/qt-console/joblist/joblist.cpp
-===================================================================
---- src/qt-console/joblist/joblist.cpp (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/joblist/joblist.cpp (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -60,6 +60,7 @@
-
- m_resultCount = 0;
- m_populated = false;
-+ m_populating = false;
- m_closeable = false;
- if ((m_mediaName != "") || (m_clientName != "") || (m_jobName != "") || (m_filesetName != ""))
- m_closeable=true;
-@@ -106,6 +107,10 @@
- */
- void JobList::populateTable()
- {
-+ if (m_populating)
-+ return;
-+ m_populating = true;
-+
- QStringList results;
- QString resultline;
- QBrush blackBrush(Qt::black);
-@@ -293,6 +298,7 @@
- tr("The Jobs query returned no results.\n"
- "Press OK to continue?"), QMessageBox::Ok );
- }
-+ m_populating = false;
- }
-
- void JobList::setStatusColor(QTableWidgetItem *item, QString &field)
-@@ -574,9 +580,9 @@
- /*
- * Graph this table
- */
--#ifdef HAVE_QWT
- void JobList::graphTable()
- {
-+#ifdef HAVE_QWT
- JobPlotPass pass;
- pass.recordLimitCheck = limitCheckBox->checkState();
- pass.daysLimitCheck = daysCheckBox->checkState();
-@@ -592,8 +598,8 @@
- pass.use = true;
- QTreeWidgetItem* pageSelectorTreeWidgetItem = mainWin->getFromHash(this);
- new JobPlot(pageSelectorTreeWidgetItem, pass);
-+#endif
- }
--#endif
-
- /*
- * Save user settings associated with this page
-Index: src/qt-console/joblist/joblist.h
-===================================================================
---- src/qt-console/joblist/joblist.h (.../tags/Release-2.4.2/bacula) (revision 7468)
-+++ src/qt-console/joblist/joblist.h (.../branches/Branch-2.4/bacula) (revision 7468)
-@@ -67,9 +67,7 @@
- void preRestoreFromTime();
- void showLogForJob();
- void consoleCancelJob();
--#ifdef HAVE_QWT
- void graphTable();
--#endif
-
- private:
- void createConnections();
-@@ -85,6 +83,7 @@
- QString m_filesetName;
- QString m_currentJob;
- bool m_populated;
-+ bool m_populating;
- bool m_checkCurrentWidget;
- int m_purgedIndex;
- int m_typeIndex;
+++ /dev/null
-
- This patch causes that jobs not yet created are now removed from
- the work queue just after the cancel command.
-
- It can be applied to 2.4.2 (not to previous versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-cancel-non-running-jobs.patch
- ./configure <your-options>
- make
- ...
- make install
-
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (révision 7681)
-+++ src/dird/job.c (copie de travail)
-@@ -354,10 +354,11 @@
- {
- BSOCK *sd, *fd;
- char ed1[50];
-+ int32_t old_status = jcr->JobStatus;
-
- set_jcr_job_status(jcr, JS_Canceled);
-
-- switch (jcr->JobStatus) {
-+ switch (old_status) {
- case JS_Created:
- case JS_WaitJobRes:
- case JS_WaitClientRes:
-
+++ /dev/null
-
- This patch fixes the seg faults that occur in the Director if an incorrect
- estimate command is given -- in particular a level specification without
- the value. This fixes bug #1140
- Apply this patch to Bacula 2.4.2 (and possibly earlier versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-estimate-cmd.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/ua_cmds.c
-===================================================================
---- src/dird/ua_cmds.c (revision 7469)
-+++ src/dird/ua_cmds.c (working copy)
-@@ -1079,17 +1079,31 @@
- strcasecmp(ua->argk[i], NT_("fd")) == 0) {
- if (ua->argv[i]) {
- client = GetClientResWithName(ua->argv[i]);
-+ if (!client) {
-+ ua->error_msg(_("Client \"%s\" not found.\n"), ua->argv[i]);
-+ return 1;
-+ }
- continue;
-+ } else {
-+ ua->error_msg(_("Client name missing.\n"));
-+ return 1;
- }
- }
- if (strcasecmp(ua->argk[i], NT_("job")) == 0) {
- if (ua->argv[i]) {
- job = GetJobResWithName(ua->argv[i]);
-- if (job && !acl_access_ok(ua, Job_ACL, job->name())) {
-+ if (!job) {
-+ ua->error_msg(_("Job \"%s\" not found.\n"), ua->argv[i]);
-+ return 1;
-+ }
-+ if (!acl_access_ok(ua, Job_ACL, job->name())) {
- ua->error_msg(_("No authorization for Job \"%s\"\n"), job->name());
- return 1;
- }
- continue;
-+ } else {
-+ ua->error_msg(_("Job name missing.\n"));
-+ return 1;
- }
- }
- if (strcasecmp(ua->argk[i], NT_("fileset")) == 0) {
-@@ -1100,15 +1114,25 @@
- return 1;
- }
- continue;
-+ } else {
-+ ua->error_msg(_("Fileset name missing.\n"));
-+ return 1;
- }
-+
- }
- if (strcasecmp(ua->argk[i], NT_("listing")) == 0) {
- listing = 1;
- continue;
- }
- if (strcasecmp(ua->argk[i], NT_("level")) == 0) {
-- if (!get_level_from_name(ua->jcr, ua->argv[i])) {
-- ua->error_msg(_("Level %s not valid.\n"), ua->argv[i]);
-+ if (ua->argv[i]) {
-+ if (!get_level_from_name(ua->jcr, ua->argv[i])) {
-+ ua->error_msg(_("Level \"%s\" not valid.\n"), ua->argv[i]);
-+ }
-+ continue;
-+ } else {
-+ ua->error_msg(_("Level value missing.\n"));
-+ return 1;
- }
- continue;
- }
+++ /dev/null
-
- Attempt to fix bug #1128 InChanger flag cleared during Migration
- job when reading from one autochanger and writing to another.
- Testing is needed.
- Apply this patch to Bacula version 2.4.2 with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-inchanger.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/dird/catreq.c
-===================================================================
---- src/dird/catreq.c (revision 7507)
-+++ src/dird/catreq.c (working copy)
-@@ -83,7 +83,7 @@
- jcr->MediaId = mr->MediaId;
- pm_strcpy(jcr->VolumeName, mr->VolumeName);
- bash_spaces(mr->VolumeName);
-- stat = bnet_fsend(sd, OK_media, mr->VolumeName, mr->VolJobs,
-+ stat = sd->fsend(OK_media, mr->VolumeName, mr->VolJobs,
- mr->VolFiles, mr->VolBlocks, edit_uint64(mr->VolBytes, ed1),
- mr->VolMounts, mr->VolErrors, mr->VolWrites,
- edit_uint64(mr->MaxVolBytes, ed2),
-@@ -266,11 +266,22 @@
- }
- }
- Dmsg2(400, "Update media: BefVolJobs=%u After=%u\n", mr.VolJobs, sdmr.VolJobs);
-+
- /* Check if the volume has been written by the job,
- * and update the LastWritten field if needed */
- if (mr.VolBlocks != sdmr.VolBlocks) {
- mr.LastWritten = sdmr.LastWritten;
- }
-+
-+ /*
-+ * Update to point to the last device used to write the Volume.
-+ * However, do so only if we are writing the tape, i.e.
-+ * the number of VolWrites has increased.
-+ */
-+ if (jcr->wstore && jcr->wstore->StorageId && sdmr.VolWrites > mr.VolWrites) {
-+ mr.StorageId = jcr->wstore->StorageId;
-+ }
-+
- /* Copy updated values to original media record */
- mr.VolJobs = sdmr.VolJobs;
- mr.VolFiles = sdmr.VolFiles;
-@@ -285,14 +296,6 @@
- mr.VolWriteTime = sdmr.VolWriteTime;
- mr.VolParts = sdmr.VolParts;
- bstrncpy(mr.VolStatus, sdmr.VolStatus, sizeof(mr.VolStatus));
-- /*
-- * Update to point to the last device used to write the Volume.
-- * However, do so only if we are writing the tape, i.e.
-- * the number of VolBlocks has increased.
-- */
-- if (jcr->wstore && jcr->wstore->StorageId && mr.VolBlocks != sdmr.VolBlocks) {
-- mr.StorageId = jcr->wstore->StorageId;
-- }
-
- Dmsg2(400, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName);
- /*
-Index: src/dird/dird.c
-===================================================================
---- src/dird/dird.c (revision 7507)
-+++ src/dird/dird.c (working copy)
-@@ -914,6 +914,7 @@
- db_create_storage_record(NULL, db, &sr);
- store->StorageId = sr.StorageId; /* set storage Id */
- if (!sr.created) { /* if not created, update it */
-+ sr.AutoChanger = store->autochanger;
- db_update_storage_record(NULL, db, &sr);
- }
-
-Index: src/cats/sql_update.c
-===================================================================
---- src/cats/sql_update.c (revision 7507)
-+++ src/cats/sql_update.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -445,7 +445,8 @@
- db_make_inchanger_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr)
- {
- char ed1[50], ed2[50];
-- if (mr->InChanger != 0 && mr->Slot != 0) {
-+ if (mr->InChanger != 0 && mr->Slot != 0 && mr->StorageId != 0 &&
-+ mr->MediaId != 0) {
- Mmsg(mdb->cmd, "UPDATE Media SET InChanger=0 WHERE "
- "Slot=%d AND StorageId=%s AND MediaId!=%s",
- mr->Slot,
+++ /dev/null
-
- This patch should fix the race condition that leads to a Director
- crash at job end time when the job list is updated. This was reported
- in bug #1162.
-
- Apply this patch to Bacula version 2.4.2 (and earlier) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-jobend-crash.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/lib/jcr.c
-===================================================================
---- src/lib/jcr.c (revision 7627)
-+++ src/lib/jcr.c (working copy)
-@@ -110,6 +110,7 @@
- void term_last_jobs_list()
- {
- if (last_jobs) {
-+ lock_last_jobs_list();
- while (!last_jobs->empty()) {
- void *je = last_jobs->first();
- last_jobs->remove(je);
-@@ -117,6 +118,7 @@
- }
- delete last_jobs;
- last_jobs = NULL;
-+ unlock_last_jobs_list();
- }
- if (jcrs) {
- delete jcrs;
-@@ -128,6 +130,7 @@
- {
- struct s_last_job *je, job;
- uint32_t num;
-+ bool ok = true;
-
- Dmsg1(100, "read_last_jobs seek to %d\n", (int)addr);
- if (addr == 0 || lseek(fd, (off_t)addr, SEEK_SET) < 0) {
-@@ -140,11 +143,13 @@
- if (num > 4 * max_last_jobs) { /* sanity check */
- return false;
- }
-+ lock_last_jobs_list();
- for ( ; num; num--) {
- if (read(fd, &job, sizeof(job)) != sizeof(job)) {
- berrno be;
- Pmsg1(000, "Read job entry. ERR=%s\n", be.bstrerror());
-- return false;
-+ ok = false;
-+ break;
- }
- if (job.JobId > 0) {
- je = (struct s_last_job *)malloc(sizeof(struct s_last_job));
-@@ -160,41 +165,48 @@
- }
- }
- }
-- return true;
-+ unlock_last_jobs_list();
-+ return ok;
- }
-
- uint64_t write_last_jobs_list(int fd, uint64_t addr)
- {
- struct s_last_job *je;
- uint32_t num;
-+ ssize_t stat;
-
- Dmsg1(100, "write_last_jobs seek to %d\n", (int)addr);
- if (lseek(fd, (off_t)addr, SEEK_SET) < 0) {
- return 0;
- }
- if (last_jobs) {
-+ lock_last_jobs_list();
- /* First record is number of entires */
- num = last_jobs->size();
- if (write(fd, &num, sizeof(num)) != sizeof(num)) {
- berrno be;
- Pmsg1(000, "Error writing num_items: ERR=%s\n", be.bstrerror());
-- return 0;
-+ goto bail_out;
- }
- foreach_dlist(je, last_jobs) {
- if (write(fd, je, sizeof(struct s_last_job)) != sizeof(struct s_last_job)) {
- berrno be;
- Pmsg1(000, "Error writing job: ERR=%s\n", be.bstrerror());
-- return 0;
-+ goto bail_out;
- }
- }
-+ unlock_last_jobs_list();
- }
- /* Return current address */
-- ssize_t stat = lseek(fd, 0, SEEK_CUR);
-+ stat = lseek(fd, 0, SEEK_CUR);
- if (stat < 0) {
- stat = 0;
- }
- return stat;
-
-+bail_out:
-+ unlock_last_jobs_list();
-+ return 0;
- }
-
- void lock_last_jobs_list()
-@@ -331,6 +343,7 @@
- last_job.end_time = time(NULL);
- /* Keep list of last jobs, but not Console where JobId==0 */
- if (last_job.JobId > 0) {
-+ lock_last_jobs_list();
- je = (struct s_last_job *)malloc(sizeof(struct s_last_job));
- memcpy((char *)je, (char *)&last_job, sizeof(last_job));
- if (!last_jobs) {
-@@ -342,6 +355,7 @@
- last_jobs->remove(je);
- free(je);
- }
-+ unlock_last_jobs_list();
- }
- break;
- default:
+++ /dev/null
-
- This patch causes a message to be printed if the migration job finds that
- the target job has already been migrated:
-
- JobId %s already migrated probably by another Job. Migration stopped.
-
- It can be applied to 2.4.2 (not to previous versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-mig-message.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 7444)
-+++ src/dird/migrate.c (working copy)
-@@ -284,6 +284,8 @@
- }
- /* Make sure this job was not already migrated */
- if (jcr->previous_jr.JobType != JT_BACKUP) {
-+ Jmsg(jcr, M_INFO, 0, _("JobId %s already migrated probably by another Job. Migration stopped.\n"),
-+ edit_int64(jcr->previous_jr.JobId, ed1));
- set_jcr_job_status(jcr, JS_Terminated);
- migration_cleanup(jcr, jcr->JobStatus);
- return true;
+++ /dev/null
-
- This patch should correct bug #1159 where Migration does not properly
- respect the Migration Low Bytes directive.
-
- Apply it to Bacula version 2.4.2 (or possibly earlier) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-migrate-poolsize.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 7566)
-+++ src/dird/migrate.c (working copy)
-@@ -557,13 +557,16 @@
- " AND Job.Type='B'"
- " ORDER by Job.StartTime";
-
--/* Get tne number of bytes in the pool */
-+/* Get the number of bytes in the pool */
- const char *sql_pool_bytes =
-- "SELECT SUM(VolBytes) FROM Media,Pool WHERE"
-+ "SELECT SUM(JobBytes) FROM Job WHERE JobId IN"
-+ " (SELECT DISTINCT Job.JobId from Pool,Job,Media,JobMedia WHERE"
-+ " Pool.Name='%s' AND Media.PoolId=Pool.PoolId AND"
- " VolStatus in ('Full','Used','Error','Append') AND Media.Enabled=1 AND"
-- " Media.PoolId=Pool.PoolId AND Pool.Name='%s'";
-+ " Job.Type='B' AND"
-+ " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId)";
-
--/* Get tne number of bytes in the Jobs */
-+/* Get the number of bytes in the Jobs */
- const char *sql_job_bytes =
- "SELECT SUM(JobBytes) FROM Job WHERE JobId IN (%s)";
-
+++ /dev/null
-
- This patch fixes migration SQL not to migrate a job that has not
- terminated, or in otherwords do not migrate a running job.
- This is a partial fix to bug #1164.
-
- Any prior patches to src/dird/migration must already be applied.
- Apply it to 2.4.2 with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-migration-deadlock.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 7729)
-+++ src/dird/migrate.c (working copy)
-@@ -554,7 +554,7 @@
- const char *sql_jobids_from_mediaid =
- "SELECT DISTINCT Job.JobId,Job.StartTime FROM JobMedia,Job"
- " WHERE JobMedia.JobId=Job.JobId AND JobMedia.MediaId IN (%s)"
-- " AND Job.Type='B'"
-+ " AND Job.Type='B' AND Job.JobStatus = 'T'"
- " ORDER by Job.StartTime";
-
- /* Get the number of bytes in the pool */
-@@ -563,7 +563,7 @@
- " (SELECT DISTINCT Job.JobId from Pool,Job,Media,JobMedia WHERE"
- " Pool.Name='%s' AND Media.PoolId=Pool.PoolId AND"
- " VolStatus in ('Full','Used','Error','Append') AND Media.Enabled=1 AND"
-- " Job.Type='B' AND"
-+ " Job.Type='B' AND Job.JobStatus = 'T' AND"
- " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId)";
-
- /* Get the number of bytes in the Jobs */
-@@ -582,7 +582,7 @@
- "SELECT DISTINCT Job.JobId from Pool,Job,Media,JobMedia WHERE"
- " Pool.Name='%s' AND Media.PoolId=Pool.PoolId AND"
- " VolStatus in ('Full','Used','Error') AND Media.Enabled=1 AND"
-- " Job.Type='B' AND"
-+ " Job.Type='B' AND Job.JobStatus = 'T' AND"
- " JobMedia.JobId=Job.JobId AND Job.PoolId=Media.PoolId"
- " AND Job.RealEndTime<='%s'";
-
+++ /dev/null
-
- This patch fixes an error when reading (restore, migration, Vbackup) and
- SD acquire.c must switch drives. The error message complained of a NULL
- volume name.
-
- Apply this patch to version 2.4.2 with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-null-vol.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/stored/acquire.c
-===================================================================
---- src/stored/acquire.c (revision 7500)
-+++ src/stored/acquire.c (working copy)
-@@ -111,10 +111,10 @@
- DIRSTORE *store;
- int stat;
-
-- Jmsg3(jcr, M_INFO, 0, _("Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
-+ Jmsg3(jcr, M_INFO, 0, _("Changing read device. Want Media Type=\"%s\" have=\"%s\"\n"
- " device=%s\n"),
- dcr->media_type, dev->device->media_type, dev->print_name());
-- Dmsg3(50, "Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
-+ Dmsg3(50, "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n"
- " device=%s\n",
- dcr->media_type, dev->device->media_type, dev->print_name());
-
-@@ -147,9 +147,9 @@
- dev = dcr->dev; /* get new device pointer */
- dev->dblock(BST_DOING_ACQUIRE);
- dcr->VolumeName[0] = 0;
-- Jmsg(jcr, M_INFO, 0, _("Media Type change. New device %s chosen.\n"),
-+ Jmsg(jcr, M_INFO, 0, _("Media Type change. New read device %s chosen.\n"),
- dev->print_name());
-- Dmsg1(50, "Media Type change. New device %s chosen.\n", dev->print_name());
-+ Dmsg1(50, "Media Type change. New read device %s chosen.\n", dev->print_name());
-
- bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
- bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
-@@ -430,11 +430,14 @@
- dcr->clear_reserved();
-
- if (dev->can_read()) {
-+ VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
- dev->clear_read(); /* clear read bit */
-- Dmsg0(100, "dir_update_vol_info. Release0\n");
-- dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
-- volume_unused(dcr);
--
-+ Dmsg2(000, "dir_update_vol_info. label=%d Vol=%s\n",
-+ dev->is_labeled(), vol->VolCatName);
-+ if (dev->is_labeled() && vol->VolCatName[0] != 0) {
-+ dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
-+ volume_unused(dcr);
-+ }
- } else if (dev->num_writers > 0) {
- /*
- * Note if WEOT is set, we are at the end of the tape
+++ /dev/null
-
- This patch fixes a missing storage name problem, which as far
- as we can tell never created any problem.
- Apply the patch to version 2.4.2 (and previous versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-storename.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/msgchan.c
-===================================================================
---- src/dird/msgchan.c (revision 7507)
-+++ src/dird/msgchan.c (working copy)
-@@ -229,6 +229,7 @@
- bash_spaces(pool_name);
- foreach_alist(storage, rstore) {
- Dmsg1(100, "Rstore=%s\n", storage->name());
-+ pm_strcpy(store_name, storage->name());
- bash_spaces(store_name);
- pm_strcpy(media_type, storage->media_type);
- bash_spaces(media_type);
+++ /dev/null
-
- This patch corrects a Verify InitCatalog problem where in certain cases
- a garbage filename may be entered in the verification database. This
- fixes bug #1143.
-
- Apply the patch to version 2.4.2 (and previous versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-verify.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/fd_cmds.c
-===================================================================
---- src/dird/fd_cmds.c (revision 7469)
-+++ src/dird/fd_cmds.c (working copy)
-@@ -616,7 +616,6 @@
- char *p, *fn;
- char Digest[MAXSTRING]; /* either Verify opts or MD5/SHA1 digest */
-
-- jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen);
- if ((len = sscanf(fd->msg, "%ld %d %s", &file_index, &stream, Digest)) != 3) {
- Jmsg(jcr, M_FATAL, 0, _("<filed: bad attributes, expected 3 fields got %d\n"
- "msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
-@@ -641,7 +640,7 @@
- }
- }
- /* Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */
-- fn = jcr->fname;
-+ fn = jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen);
- while (*p != 0) {
- *fn++ = *p++; /* copy filename */
- }
+++ /dev/null
-
- This patch fixes a case problem in an SQL command, and could potentially
- fix the DiskToCatalog problem reported in bug #1149.
- Apply the patch to version 2.4.2 (and previous versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.2-verifydisk.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/cats/sql_get.c
-===================================================================
---- src/cats/sql_get.c (revision 7507)
-+++ src/cats/sql_get.c (working copy)
-@@ -109,7 +109,7 @@
- Mmsg(mdb->cmd,
- "SELECT FileId, LStat, MD5 FROM File,Job WHERE "
- "File.JobId=Job.JobId AND File.PathId=%s AND "
--"File.FilenameId=%s AND Job.Type='B' AND Job.JobSTATUS='T' AND "
-+"File.FilenameId=%s AND Job.Type='B' AND Job.JobStatus='T' AND "
- "ClientId=%s ORDER BY StartTime DESC LIMIT 1",
- edit_int64(fdbr->PathId, ed1),
- edit_int64(fdbr->FilenameId, ed2),
+++ /dev/null
-
- This patch used the jcr stored in the BSOCK packet during callbacks
- to the Director rather than looking them up in the JCR list.
-
- It can be applied to Bacula version 2.4.3 (or earlier) with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-getmsg.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/dird/getmsg.c
-===================================================================
---- src/dird/getmsg.c (revision 7970)
-+++ src/dird/getmsg.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -20,7 +20,7 @@
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-- Bacula® is a registered trademark of John Walker.
-+ Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-@@ -102,12 +102,12 @@
- char Job[MAX_NAME_LENGTH];
- char MsgType[20];
- int type, level;
-- JCR *jcr;
-+ JCR *jcr = bs->jcr();
- char *msg;
-
- for (;;) {
- n = bs->recv();
-- Dmsg2(100, "bget_dirmsg %d: %s", n, bs->msg);
-+ Dmsg2(300, "bget_dirmsg %d: %s\n", n, bs->msg);
-
- if (is_bnet_stop(bs)) {
- return n; /* error or terminate */
-@@ -142,7 +142,7 @@
- bs->fsend("btime %s\n", edit_uint64(get_current_btime(),ed1));
- break;
- default:
-- Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen);
-+ Jmsg1(jcr, M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen);
- return n;
- }
- continue;
-@@ -160,21 +160,13 @@
- * Try to fulfill it.
- */
- if (sscanf(bs->msg, "%020s Job=%127s ", MsgType, Job) != 2) {
-- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
-+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- continue;
- }
-- if (strcmp(Job, "*System*") == 0) {
-- jcr = NULL; /* No jcr */
-- } else if (!(jcr=get_jcr_by_full_name(Job))) {
-- Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg);
-- continue;
-- }
-- Dmsg1(900, "Getmsg got jcr 0x%x\n", jcr);
-
- /* Skip past "Jmsg Job=nnn" */
- if (!(msg=find_msg_start(bs->msg))) {
-- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
-- free_jcr(jcr);
-+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- continue;
- }
-
-@@ -185,8 +177,7 @@
- if (bs->msg[0] == 'J') { /* Job message */
- if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d",
- Job, &type, &level) != 3) {
-- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
-- free_jcr(jcr);
-+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- continue;
- }
- Dmsg1(900, "Got msg: %s\n", bs->msg);
-@@ -199,7 +190,6 @@
- }
- Dmsg1(900, "Dispatch msg: %s", msg);
- dispatch_message(jcr, type, level, msg);
-- free_jcr(jcr);
- continue;
- }
- /*
-@@ -209,21 +199,16 @@
- if (bs->msg[0] == 'C') { /* Catalog request */
- Dmsg2(900, "Catalog req jcr 0x%x: %s", jcr, bs->msg);
- catalog_request(jcr, bs);
-- Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
-- free_jcr(jcr);
- continue;
- }
- if (bs->msg[0] == 'U') { /* SD sending attributes */
- Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
- catalog_update(jcr, bs);
-- Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
-- free_jcr(jcr);
- continue;
- }
- if (bs->msg[0] == 'M') { /* Mount request */
- Dmsg1(900, "Mount req: %s", bs->msg);
- mount_request(jcr, bs, msg);
-- free_jcr(jcr);
- continue;
- }
- if (bs->msg[0] == 'S') { /* Status change */
-@@ -232,9 +217,8 @@
- if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
- jcr->SDJobStatus = JobStatus; /* current status */
- } else {
-- Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
-+ Jmsg1(jcr, M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- }
-- free_jcr(jcr);
- continue;
- }
- #ifdef needed
+++ /dev/null
-
- This patch corrects two problems:
- 1. If you start more than 60 jobs within a 1 minute period, the unique
- jobname (critical for the daemons) can be duplicated leading to
- authentication failures and orphaned jobs.
- 2. FD jobs that fail SD authentication were not properly cleaned up.
-
- Apply it to Bacula 2.4.3 (possibly earlier versions)
- with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-jobs.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (revision 8011)
-+++ src/dird/job.c (working copy)
-@@ -758,17 +758,17 @@
- static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- static time_t last_start_time = 0;
- static int seq = 0;
-- time_t now;
-+ time_t now = time(NULL);
- struct tm tm;
- char dt[MAX_TIME_LENGTH];
- char name[MAX_NAME_LENGTH];
- char *p;
-+ int len;
-
- /* Guarantee unique start time -- maximum one per second, and
- * thus unique Job Name
- */
- P(mutex); /* lock creation of jobs */
-- now = time(NULL);
- seq++;
- if (seq > 59) { /* wrap as if it is seconds */
- seq = 0;
-@@ -783,9 +783,10 @@
- /* Form Unique JobName */
- (void)localtime_r(&now, &tm);
- /* Use only characters that are permitted in Windows filenames */
-- strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M", &tm);
-+ strftime(dt, sizeof(dt), "%Y-%m-%d_%H.%M.%S", &tm);
-+ len = strlen(dt) + 5; /* dt + .%02d EOS */
- bstrncpy(name, base_name, sizeof(name));
-- name[sizeof(name)-22] = 0; /* truncate if too long */
-+ name[sizeof(name)-len] = 0; /* truncate if too long */
- bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s.%02d", name, dt, seq); /* add date & time */
- /* Convert spaces into underscores */
- for (p=jcr->Job; *p; p++) {
-@@ -793,6 +794,7 @@
- *p = '_';
- }
- }
-+ Dmsg2(100, "JobId=%u created Job=%s\n", jcr->JobId, jcr->Job);
- }
-
- /* Called directly from job rescheduling */
-Index: src/stored/job.c
-===================================================================
---- src/stored/job.c (revision 8011)
-+++ src/stored/job.c (working copy)
-@@ -228,21 +228,25 @@
- if (!(jcr=get_jcr_by_full_name(job_name))) {
- Jmsg1(NULL, M_FATAL, 0, _("FD connect failed: Job name not found: %s\n"), job_name);
- Dmsg1(3, "**** Job \"%s\" not found\n", job_name);
-+ fd->close();
- return;
- }
-
-- jcr->file_bsock = fd;
-- jcr->file_bsock->set_jcr(jcr);
--
- Dmsg1(110, "Found Job %s\n", job_name);
-
- if (jcr->authenticated) {
- Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"),
- (uint32_t)jcr->JobId, jcr->Job);
-+ Dmsg2(50, "Hey!!!! JobId %u Job %s already authenticated.\n",
-+ (uint32_t)jcr->JobId, jcr->Job);
-+ fd->close();
- free_jcr(jcr);
- return;
- }
-
-+ jcr->file_bsock = fd;
-+ jcr->file_bsock->set_jcr(jcr);
-+
- /*
- * Authenticate the File daemon
- */
-Index: src/lib/bnet_server.c
-===================================================================
---- src/lib/bnet_server.c (revision 8011)
-+++ src/lib/bnet_server.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2000-2008 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.
-@@ -20,7 +20,7 @@
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-- Bacula® is a registered trademark of John Walker.
-+ Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-@@ -137,7 +137,7 @@
- be.bstrerror());
- }
- }
-- listen(fd_ptr->fd, 5); /* tell system we are ready */
-+ listen(fd_ptr->fd, 20); /* tell system we are ready */
- sockfds.append(fd_ptr);
- }
- /* Start work queue thread */
+++ /dev/null
-
- This patch should cause all Job Log records to be migrated when the
- Job is migrated. It fixes the second issue reported in bug #1171.
-
- Apply it to Bacula 2.4.3 (possibly earlier versions)
- with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-migrate.patch
- ./configure <your-options>
- make
- ...
- make install
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 7926)
-+++ src/dird/migrate.c (working copy)
-@@ -402,14 +402,6 @@
- }
-
- migration_cleanup(jcr, jcr->JobStatus);
-- if (mig_jcr) {
-- char jobid[50];
-- UAContext *ua = new_ua_context(jcr);
-- edit_uint64(jcr->previous_jr.JobId, jobid);
-- /* Purge all old file records, but leave Job record */
-- purge_files_from_jobs(ua, jobid);
-- free_ua_context(ua);
-- }
- return true;
- }
-
-@@ -1087,11 +1079,26 @@
- edit_uint64(mig_jcr->jr.JobId, ec2));
- db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
-
-- /* Now mark the previous job as migrated if it terminated normally */
-- if (jcr->JobStatus == JS_Terminated) {
-+ /*
-+ * If we terminated a migration normally:
-+ * - mark the previous job as migrated
-+ * - move any Log records to the new JobId
-+ * - Purge the File records from the previous job
-+ */
-+ if (jcr->JobType == JT_MIGRATE && jcr->JobStatus == JS_Terminated) {
-+ char old_jobid[50], new_jobid[50];
- Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s",
-- (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, ec1));
-+ (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid));
- db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
-+ UAContext *ua = new_ua_context(jcr);
-+ /* Move JobLog to new JobId */
-+ Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s",
-+ new_jobid,
-+ edit_uint64(jcr->previous_jr.JobId, old_jobid));
-+ db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
-+ /* Purge all old file records, but leave Job record */
-+ purge_files_from_jobs(ua, old_jobid);
-+ free_ua_context(ua);
- }
-
- if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
-@@ -1100,7 +1107,6 @@
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- }
-
--
- update_bootstrap_file(mig_jcr);
-
- if (!db_get_job_volume_names(mig_jcr, mig_jcr->db, mig_jcr->jr.JobId, &mig_jcr->VolumeName)) {
+++ /dev/null
-
- This patch should prevent migration jobs from attempting to migrate
- jobs that failed. Apply it to Bacula 2.4.3 (possibly earlier versions)
- with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-migrate.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 7757)
-+++ src/dird/migrate.c (working copy)
-@@ -377,7 +377,7 @@
- * to avoid two threads from using the BSOCK structure at
- * the same time.
- */
-- if (!bnet_fsend(sd, "run")) {
-+ if (!sd->fsend("run")) {
- return false;
- }
-
-@@ -520,6 +520,7 @@
- "SELECT DISTINCT Job.JobId,Job.StartTime FROM Job,Pool,Client"
- " WHERE Client.Name='%s' AND Pool.Name='%s' AND Job.PoolId=Pool.PoolId"
- " AND Job.ClientId=Client.ClientId AND Job.Type='B'"
-+ " AND Job.JobStatus = 'T'"
- " ORDER by Job.StartTime";
-
- /* Get Volume names in Pool */
-@@ -533,9 +534,9 @@
- "SELECT DISTINCT Job.JobId,Job.StartTime FROM Media,JobMedia,Job"
- " WHERE Media.VolumeName='%s' AND Media.MediaId=JobMedia.MediaId"
- " AND JobMedia.JobId=Job.JobId AND Job.Type='B'"
-+ " AND Job.JobStatus = 'T' AND Media.Enabled=1"
- " ORDER by Job.StartTime";
-
--
- const char *sql_smallest_vol =
- "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE"
- " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND"
-@@ -570,7 +571,6 @@
- const char *sql_job_bytes =
- "SELECT SUM(JobBytes) FROM Job WHERE JobId IN (%s)";
-
--
- /* Get Media Ids in Pool */
- const char *sql_mediaids =
- "SELECT MediaId FROM Media,Pool WHERE"
+++ /dev/null
-
- This patch should fix two bugs:
- - Bug #1206 -- sql error when there are no files to migrate.
- - Bug #1171 -- Job catalog log is not migrated during migration.
-
- Apply it to a fully patched (requires two previous migration patches)
- 2.4.3 version with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-migrate2.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 8152)
-+++ src/dird/migrate.c (working copy)
-@@ -122,6 +122,12 @@
-
- Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->rpool->name(), jcr->rpool_source);
-
-+ if (!get_or_create_fileset_record(jcr)) {
-+ Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId);
-+ Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
-+ return false;
-+ }
-+
- /* If we find a job or jobs to migrate it is previous_jr.JobId */
- count = get_job_to_migrate(jcr);
- if (count < 0) {
-@@ -139,12 +145,6 @@
- return true; /* no work */
- }
-
-- if (!get_or_create_fileset_record(jcr)) {
-- Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId);
-- Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
-- return false;
-- }
--
- create_restore_bootstrap_file(jcr);
-
- if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) {
-@@ -1062,6 +1062,11 @@
- * mig_jcr is jcr of the newly migrated job.
- */
- if (mig_jcr) {
-+ char old_jobid[50], new_jobid[50];
-+
-+ edit_uint64(jcr->previous_jr.JobId, old_jobid);
-+ edit_uint64(mig_jcr->jr.JobId, new_jobid);
-+
- mig_jcr->JobFiles = jcr->JobFiles = jcr->SDJobFiles;
- mig_jcr->JobBytes = jcr->JobBytes = jcr->SDJobBytes;
- mig_jcr->VolSessionId = jcr->VolSessionId;
-@@ -1076,7 +1081,7 @@
- "JobTDate=%s WHERE JobId=%s",
- jcr->previous_jr.cStartTime, jcr->previous_jr.cEndTime,
- edit_uint64(jcr->previous_jr.JobTDate, ec1),
-- edit_uint64(mig_jcr->jr.JobId, ec2));
-+ new_jobid);
- db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
-
- /*
-@@ -1086,15 +1091,13 @@
- * - Purge the File records from the previous job
- */
- if (jcr->JobType == JT_MIGRATE && jcr->JobStatus == JS_Terminated) {
-- char old_jobid[50], new_jobid[50];
- Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s",
-- (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid));
-+ (char)JT_MIGRATED_JOB, old_jobid);
- db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
- UAContext *ua = new_ua_context(jcr);
- /* Move JobLog to new JobId */
- Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s",
-- new_jobid,
-- edit_uint64(jcr->previous_jr.JobId, old_jobid));
-+ new_jobid, old_jobid);
- db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
- /* Purge all old file records, but leave Job record */
- purge_files_from_jobs(ua, old_jobid);
+++ /dev/null
-
- This patch fixes a case of orphaned jobs (and possible deadlock)
- during pruning.
- Apply it to Bacula 2.4.3 (possibly earlier versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-orphaned-jobs.patch
- ./configure <your-options>
- make
- ...
- make install
-
-Index: src/dird/ua_prune.c
-===================================================================
---- src/dird/ua_prune.c (revision 7949)
-+++ src/dird/ua_prune.c (working copy)
-@@ -468,6 +468,7 @@
- break;
- }
- }
-+ endeach_jcr(jcr);
- if (skip) {
- continue;
- }
+++ /dev/null
-
- This patch should fix the bug reported on the bacula-users list where
- a retention period of 100 years does immediate prunning.
- Apply it to 2.4.3 (or earlier versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-prune.patch
- ./configure <your-options>
- make
- ...
- make install
-
-Index: src/dird/ua_prune.c
-===================================================================
---- src/dird/ua_prune.c (revision 7757)
-+++ src/dird/ua_prune.c (working copy)
-@@ -202,7 +202,7 @@
- now = (utime_t)time(NULL);
-
- /* Select Jobs -- for counting */
-- Mmsg(query, count_select_job, edit_uint64(now - period, ed1),
-+ Mmsg(query, count_select_job, edit_int64(now - period, ed1),
- edit_int64(cr.ClientId, ed2));
- Dmsg3(050, "select now=%u period=%u sql=%s\n", (uint32_t)now,
- (uint32_t)period, query.c_str());
-@@ -230,7 +230,7 @@
- del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
-
- /* Now process same set but making a delete list */
-- Mmsg(query, select_job, edit_uint64(now - period, ed1),
-+ Mmsg(query, select_job, edit_int64(now - period, ed1),
- edit_int64(cr.ClientId, ed2));
- db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del);
-
-@@ -318,7 +318,7 @@
- * Select all files that are older than the JobRetention period
- * and stuff them into the "DeletionCandidates" table.
- */
-- edit_uint64(now - period, ed1);
-+ edit_int64(now - period, ed1);
- Mmsg(query, insert_delcand, (char)JobType, ed1,
- edit_int64(cr.ClientId, ed2));
- if (!db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL)) {
-@@ -443,10 +443,10 @@
- edit_int64(mr->MediaId, ed1);
- period = mr->VolRetention;
- now = (utime_t)time(NULL);
-- edit_uint64(now-period, ed2);
-+ edit_int64(now-period, ed2);
- Mmsg(query, sel_JobMedia, ed1, ed2);
-- Dmsg3(250, "Now=%d period=%d now-period=%d\n", (int)now, (int)period,
-- (int)(now-period));
-+ Dmsg3(250, "Now=%d period=%d now-period=%s\n", (int)now, (int)period,
-+ ed2);
-
- Dmsg1(050, "Query=%s\n", query.c_str());
- if (!db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)del)) {
+++ /dev/null
-
- This patch corrects appears to fix bug #1188, where a Volume can
- be purged while it is being written.
-
- Apply it to Bacula 2.4.3 (possibly earlier versions)
- with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-purge-bug.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/dird/ua_purge.c
-===================================================================
---- src/dird/ua_purge.c (revision 8054)
-+++ src/dird/ua_purge.c (working copy)
-@@ -463,6 +463,9 @@
- bool purged = false;
- char ed1[50];
-
-+ if (mr->FirstWritten == 0 || mr->LastWritten == 0) {
-+ goto bail_out; /* not written cannot purge */
-+ }
- if (strcmp(mr->VolStatus, "Purged") == 0) {
- purged = true;
- goto bail_out;
+++ /dev/null
-
- This patch fix #1110 about a problem when executing a program with
- Unicode path.
-
- It can be applied to 2.4.3 (and previous versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.3-win32-runscript-unicode-path.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-Index: src/win32/compat/compat.cpp
-===================================================================
---- src/win32/compat/compat.cpp (révision 7772)
-+++ src/win32/compat/compat.cpp (copie de travail)
-@@ -1807,6 +1807,97 @@
- }
-
- /**
-+ * Create the process with UTF8 API
-+ */
-+static BOOL
-+CreateChildProcessW(const char *comspec, const char *cmdLine,
-+ PROCESS_INFORMATION *hProcInfo,
-+ HANDLE in, HANDLE out, HANDLE err)
-+{
-+ STARTUPINFOW siStartInfo;
-+ BOOL bFuncRetn = FALSE;
-+
-+ // Set up members of the STARTUPINFO structure.
-+ ZeroMemory( &siStartInfo, sizeof(siStartInfo) );
-+ siStartInfo.cb = sizeof(siStartInfo);
-+ // setup new process to use supplied handles for stdin,stdout,stderr
-+
-+ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
-+ siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE;
-+
-+ siStartInfo.hStdInput = in;
-+ siStartInfo.hStdOutput = out;
-+ siStartInfo.hStdError = err;
-+
-+ // Convert argument to WCHAR
-+ POOLMEM *cmdLine_wchar = get_pool_memory(PM_FNAME);
-+ POOLMEM *comspec_wchar = get_pool_memory(PM_FNAME);
-+
-+ UTF8_2_wchar(&cmdLine_wchar, cmdLine);
-+ UTF8_2_wchar(&comspec_wchar, comspec);
-+
-+ // Create the child process.
-+ Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec_wchar, cmdLine_wchar);
-+
-+ // try to execute program
-+ bFuncRetn = p_CreateProcessW((WCHAR*)comspec_wchar,
-+ (WCHAR*)cmdLine_wchar,// command line
-+ NULL, // process security attributes
-+ NULL, // primary thread security attributes
-+ TRUE, // handles are inherited
-+ 0, // creation flags
-+ NULL, // use parent's environment
-+ NULL, // use parent's current directory
-+ &siStartInfo, // STARTUPINFO pointer
-+ hProcInfo); // receives PROCESS_INFORMATION
-+
-+ free_pool_memory(cmdLine_wchar);
-+ free_pool_memory(comspec_wchar);
-+
-+ return bFuncRetn;
-+}
-+
-+
-+/**
-+ * Create the process with ANSI API
-+ */
-+static BOOL
-+CreateChildProcessA(const char *comspec, char *cmdLine,
-+ PROCESS_INFORMATION *hProcInfo,
-+ HANDLE in, HANDLE out, HANDLE err)
-+{
-+ STARTUPINFOA siStartInfo;
-+ BOOL bFuncRetn = FALSE;
-+
-+ // Set up members of the STARTUPINFO structure.
-+ ZeroMemory( &siStartInfo, sizeof(siStartInfo) );
-+ siStartInfo.cb = sizeof(siStartInfo);
-+ // setup new process to use supplied handles for stdin,stdout,stderr
-+ siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
-+ siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE;
-+
-+ siStartInfo.hStdInput = in;
-+ siStartInfo.hStdOutput = out;
-+ siStartInfo.hStdError = err;
-+
-+ // Create the child process.
-+ Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine);
-+
-+ // try to execute program
-+ bFuncRetn = p_CreateProcessA(comspec,
-+ cmdLine, // command line
-+ NULL, // process security attributes
-+ NULL, // primary thread security attributes
-+ TRUE, // handles are inherited
-+ 0, // creation flags
-+ NULL, // use parent's environment
-+ NULL, // use parent's current directory
-+ &siStartInfo,// STARTUPINFO pointer
-+ hProcInfo);// receives PROCESS_INFORMATION
-+ return bFuncRetn;
-+}
-+
-+/**
- * OK, so it would seem CreateProcess only handles true executables:
- * .com or .exe files. So grab $COMSPEC value and pass command line to it.
- */
-@@ -1815,44 +1906,30 @@
- {
- static const char *comspec = NULL;
- PROCESS_INFORMATION piProcInfo;
-- STARTUPINFOA siStartInfo;
- BOOL bFuncRetn = FALSE;
-
-- if (comspec == NULL) {
-+ if (!p_CreateProcessA || !p_CreateProcessW)
-+ return INVALID_HANDLE_VALUE;
-+
-+ if (comspec == NULL)
- comspec = getenv("COMSPEC");
-- }
- if (comspec == NULL) // should never happen
- return INVALID_HANDLE_VALUE;
-
- // Set up members of the PROCESS_INFORMATION structure.
- ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
-
-- // Set up members of the STARTUPINFO structure.
--
-- ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
-- siStartInfo.cb = sizeof(STARTUPINFO);
-- // setup new process to use supplied handles for stdin,stdout,stderr
- // if supplied handles are not used the send a copy of our STD_HANDLE
- // as appropriate
-- siStartInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
-- siStartInfo.wShowWindow = SW_SHOWMINNOACTIVE;
-+ if (in == INVALID_HANDLE_VALUE)
-+ in = GetStdHandle(STD_INPUT_HANDLE);
-
-- if (in != INVALID_HANDLE_VALUE)
-- siStartInfo.hStdInput = in;
-- else
-- siStartInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
-+ if (out == INVALID_HANDLE_VALUE)
-+ out = GetStdHandle(STD_OUTPUT_HANDLE);
-
-- if (out != INVALID_HANDLE_VALUE)
-- siStartInfo.hStdOutput = out;
-- else
-- siStartInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
-- if (err != INVALID_HANDLE_VALUE)
-- siStartInfo.hStdError = err;
-- else
-- siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
-+ if (err == INVALID_HANDLE_VALUE)
-+ err = GetStdHandle(STD_ERROR_HANDLE);
-
-- // Create the child process.
--
- char *exeFile;
- const char *argStart;
-
-@@ -1860,43 +1937,32 @@
- return INVALID_HANDLE_VALUE;
- }
-
-- int cmdLen = strlen(comspec) + 4 + strlen(exeFile) + strlen(argStart) + 1;
-+ POOL_MEM cmdLine(PM_FNAME);
-+ Mmsg(cmdLine, "%s /c %s%s", comspec, exeFile, argStart);
-
-- char *cmdLine = (char *)alloca(cmdLen);
--
-- snprintf(cmdLine, cmdLen, "%s /c %s%s", comspec, exeFile, argStart);
--
- free(exeFile);
-
-- Dmsg2(150, "Calling CreateProcess(%s, %s, ...)\n", comspec, cmdLine);
-+ if (p_CreateProcessW && p_MultiByteToWideChar) {
-+ bFuncRetn = CreateChildProcessW(comspec, cmdLine.c_str(), &piProcInfo,
-+ in, out, err);
-+ } else {
-+ bFuncRetn = CreateChildProcessA(comspec, cmdLine.c_str(), &piProcInfo,
-+ in, out, err);
-+ }
-
-- // try to execute program
-- bFuncRetn = CreateProcessA(comspec,
-- cmdLine, // command line
-- NULL, // process security attributes
-- NULL, // primary thread security attributes
-- TRUE, // handles are inherited
-- 0, // creation flags
-- NULL, // use parent's environment
-- NULL, // use parent's current directory
-- &siStartInfo, // STARTUPINFO pointer
-- &piProcInfo); // receives PROCESS_INFORMATION
--
- if (bFuncRetn == 0) {
- ErrorExit("CreateProcess failed\n");
- const char *err = errorString();
-- Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n", comspec, cmdLine, err);
-+ Dmsg3(99, "CreateProcess(%s, %s, ...)=%s\n",comspec,cmdLine.c_str(),err);
- LocalFree((void *)err);
- return INVALID_HANDLE_VALUE;
- }
- // we don't need a handle on the process primary thread so we close
- // this now.
- CloseHandle(piProcInfo.hThread);
--
- return piProcInfo.hProcess;
- }
-
--
- void
- ErrorExit (LPCSTR lpszMessage)
- {
-Index: src/win32/compat/winapi.c
-===================================================================
---- src/win32/compat/winapi.c (révision 7772)
-+++ src/win32/compat/winapi.c (copie de travail)
-@@ -88,6 +88,9 @@
-
- t_SHGetFolderPath p_SHGetFolderPath = NULL;
-
-+t_CreateProcessA p_CreateProcessA = NULL;
-+t_CreateProcessW p_CreateProcessW = NULL;
-+
- void
- InitWinAPIWrapper()
- {
-@@ -104,6 +107,12 @@
-
- HMODULE hLib = LoadLibraryA("KERNEL32.DLL");
- if (hLib) {
-+ /* create process calls */
-+ p_CreateProcessA = (t_CreateProcessA)
-+ GetProcAddress(hLib, "CreateProcessA");
-+ p_CreateProcessW = (t_CreateProcessW)
-+ GetProcAddress(hLib, "CreateProcessW");
-+
- /* create file calls */
- p_CreateFileA = (t_CreateFileA)
- GetProcAddress(hLib, "CreateFileA");
-Index: src/win32/winapi.h
-===================================================================
---- src/win32/winapi.h (révision 7772)
-+++ src/win32/winapi.h (copie de travail)
-@@ -138,6 +138,32 @@
-
- typedef BOOL (WINAPI * t_AttachConsole) (DWORD);
-
-+typedef BOOL (WINAPI *t_CreateProcessA) (
-+ LPCSTR,
-+ LPSTR,
-+ LPSECURITY_ATTRIBUTES,
-+ LPSECURITY_ATTRIBUTES,
-+ BOOL,
-+ DWORD,
-+ PVOID,
-+ LPCSTR,
-+ LPSTARTUPINFOA,
-+ LPPROCESS_INFORMATION);
-+typedef BOOL (WINAPI *t_CreateProcessW) (
-+ LPCWSTR,
-+ LPWSTR,
-+ LPSECURITY_ATTRIBUTES,
-+ LPSECURITY_ATTRIBUTES,
-+ BOOL,
-+ DWORD,
-+ PVOID,
-+ LPCWSTR,
-+ LPSTARTUPINFOW,
-+ LPPROCESS_INFORMATION);
-+
-+extern t_CreateProcessA DLL_IMP_EXP p_CreateProcessA;
-+extern t_CreateProcessW DLL_IMP_EXP p_CreateProcessW;
-+
- extern t_GetFileAttributesA DLL_IMP_EXP p_GetFileAttributesA;
- extern t_GetFileAttributesW DLL_IMP_EXP p_GetFileAttributesW;
-
+++ /dev/null
-
- This patch fixes bat.pro.in so that bat will install correctly.
-
- Apply it to version 2.4.4 with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-bat-install.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/qt-console/bat.pro.in
-===================================================================
---- src/qt-console/bat.pro.in (revision 8326)
-+++ src/qt-console/bat.pro.in (working copy)
-@@ -9,9 +9,9 @@
- #
- CONFIG += qt debug @QWT@
-
--bins.path = /$(DESTDIR)@sbindir@
-+bins.path = $(DESTDIR)@sbindir@
- bins.files = ./bat
--confs.path = /$(DESTDIR)@sysconfdir@
-+confs.path = $(DESTDIR)@sysconfdir@
- confs.commands = ./install_conf_file
-
- TEMPLATE = app
+++ /dev/null
-
- This patch fixes bug #1255 'variable %n changed'
-
- Apply it to version 2.4.4 with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-jobname-edit.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (revision 8455)
-+++ src/dird/job.c (working copy)
-@@ -787,7 +787,7 @@
- len = strlen(dt) + 5; /* dt + .%02d EOS */
- bstrncpy(name, base_name, sizeof(name));
- name[sizeof(name)-len] = 0; /* truncate if too long */
-- bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s.%02d", name, dt, seq); /* add date & time */
-+ bsnprintf(jcr->Job, sizeof(jcr->Job), "%s.%s_%02d", name, dt, seq); /* add date & time */
- /* Convert spaces into underscores */
- for (p=jcr->Job; *p; p++) {
- if (*p == ' ') {
+++ /dev/null
- [label-failure.patch] IQ
- This patch should fix the problems labeling a tape while
- Bacula is requesting you to mount or label a new tape.
- It should also fix problems where Bacula will not recognize
- that a new tape is inserted or created and it keeps asking for
- a different tape. It fixes bug #1227.
-
- Apply it to 2.4.4 (possibly earlier versions) with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-label-failure.patch
- ./configure <your-options>
- make
- ...
- make install
- ...
-
-
-
-Index: src/stored/wait.c
-===================================================================
---- src/stored/wait.c (revision 8605)
-+++ src/stored/wait.c (working copy)
-@@ -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.
-@@ -20,7 +20,7 @@
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-- Bacula® is a registered trademark of John Walker.
-+ Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-@@ -62,8 +62,14 @@
-
- dev->dlock();
- Dmsg1(dbglvl, "Enter blocked=%s\n", dev->print_blocked());
-+
-+ /*
-+ * Since we want to mount a tape, make sure current one is
-+ * not marked as using this drive.
-+ */
-+ volume_unused(dcr);
-+
- unmounted = is_device_unmounted(dev);
--
- dev->poll = false;
- /*
- * Wait requested time (dev->rem_wait_sec). However, we also wake up every
-Index: src/stored/reserve.c
-===================================================================
---- src/stored/reserve.c (revision 8605)
-+++ src/stored/reserve.c (working copy)
-@@ -20,7 +20,7 @@
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-- Bacula® is a registered trademark of John Walker.
-+ Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-@@ -346,8 +346,12 @@
- goto get_out;
- }
- Dmsg3(dbglvl, "jid=%u reserve_vol free vol=%s at %p\n", jid(), vol->vol_name, vol->vol_name);
-- free_volume(dev);
-- dev->set_unload(); /* have to unload current volume */
-+ /* If old Volume is still mounted, must unload it */
-+ if (strcmp(vol->vol_name, dev->VolHdr.VolumeName) == 0) {
-+ Dmsg0(50, "set_unload\n");
-+ dev->set_unload(); /* have to unload current volume */
-+ }
-+ free_volume(dev); /* Release old volume entry */
- debug_list_volumes("reserve_vol free");
- }
- }
+++ /dev/null
-
- This patch fixes bug #1211 crash during reload with bad dird.conf file.
-
- Apply it to version 2.4.4 with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-reload.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/lib/parse_conf.c
-===================================================================
---- src/lib/parse_conf.c (revision 8393)
-+++ src/lib/parse_conf.c (working copy)
-@@ -284,6 +284,7 @@
- }
- if (token != T_EQUALS) {
- scan_err1(lc, _("expected an =, got: %s"), lc->str);
-+ return;
- }
- break;
- }
-@@ -304,6 +305,7 @@
- Dmsg1(900, "store_msgs dest=%s:\n", NPRT(dest));
- if (token != T_EQUALS) {
- scan_err1(lc, _("expected an =, got: %s"), lc->str);
-+ return;
- }
- scan_types(lc, (MSGS *)(item->value), item->code, dest, NULL);
- free_pool_memory(dest);
-@@ -312,7 +314,7 @@
-
- default:
- scan_err1(lc, _("Unknown item code: %d\n"), item->code);
-- break;
-+ return;
- }
- }
- scan_to_eol(lc);
-@@ -352,7 +354,7 @@
- }
- if (!found) {
- scan_err1(lc, _("message type: %s not found"), str);
-- /* NOT REACHED */
-+ return;
- }
-
- if (msg_type == M_MAX+1) { /* all? */
-@@ -384,12 +386,14 @@
- lex_get_token(lc, T_NAME);
- if (!is_name_valid(lc->str, &msg)) {
- scan_err1(lc, "%s\n", msg);
-+ return;
- }
- free_pool_memory(msg);
- /* Store the name both pass 1 and pass 2 */
- if (*(item->value)) {
- scan_err2(lc, _("Attempt to redefine name \"%s\" to \"%s\"."),
- *(item->value), lc->str);
-+ return;
- }
- *(item->value) = bstrdup(lc->str);
- scan_to_eol(lc);
-@@ -481,10 +485,12 @@
- if (res == NULL) {
- scan_err3(lc, _("Could not find config Resource %s referenced on line %d : %s\n"),
- lc->str, lc->line_no, lc->line);
-+ return;
- }
- if (*(item->value)) {
- scan_err3(lc, _("Attempt to redefine resource \"%s\" referenced on line %d : %s\n"),
- item->name, lc->line_no, lc->line);
-+ return;
- }
- *(item->value) = (char *)res;
- }
-@@ -520,6 +526,7 @@
- if (i >= count) {
- scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"),
- lc->str, count, lc->line_no, lc->line);
-+ return;
- }
- list = New(alist(10, not_owned_by_alist));
- }
-@@ -530,6 +537,7 @@
- if (res == NULL) {
- scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"),
- item->name, lc->line_no, lc->line);
-+ return;
- }
- Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n",
- res, list, list->size(), i, item->name);
-@@ -592,6 +600,7 @@
- if (res == NULL) {
- scan_err3(lc, _("Missing config Resource \"%s\" referenced on line %d : %s\n"),
- lc->str, lc->line_no, lc->line);
-+ return;
- }
- }
- scan_to_eol(lc);
-@@ -655,12 +664,13 @@
- }
- if (!size_to_uint64(bsize, strlen(bsize), &uvalue)) {
- scan_err1(lc, _("expected a size number, got: %s"), lc->str);
-+ return;
- }
- *(uint64_t *)(item->value) = uvalue;
- break;
- default:
- scan_err1(lc, _("expected a size, got: %s"), lc->str);
-- break;
-+ return;
- }
- if (token != T_EOL) {
- scan_to_eol(lc);
-@@ -697,12 +707,13 @@
- }
- if (!duration_to_utime(period, &utime)) {
- scan_err1(lc, _("expected a time period, got: %s"), period);
-+ return;
- }
- *(utime_t *)(item->value) = utime;
- break;
- default:
- scan_err1(lc, _("expected a time period, got: %s"), lc->str);
-- break;
-+ return;
- }
- if (token != T_EOL) {
- scan_to_eol(lc);
-@@ -721,6 +732,7 @@
- *(uint32_t *)(item->value) &= ~(item->code);
- } else {
- scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
-+ return;
- }
- scan_to_eol(lc);
- set_bit(index, res_all.hdr.item_present);
-@@ -736,6 +748,7 @@
- *(bool *)(item->value) = false;
- } else {
- scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
-+ return;
- }
- scan_to_eol(lc);
- set_bit(index, res_all.hdr.item_present);
-@@ -761,6 +774,7 @@
- }
- if (i != 0) {
- scan_err1(lc, _("Expected a Tape Label keyword, got: %s"), lc->str);
-+ return;
- }
- scan_to_eol(lc);
- set_bit(index, res_all.hdr.item_present);
-@@ -910,6 +924,7 @@
- Dmsg0(900, "T_EOB => define new resource\n");
- if (res_all.hdr.name == NULL) {
- scan_err0(lc, _("Name not specified for resource"));
-+ return 0;
- }
- save_resource(res_type, items, pass); /* save resource */
- break;
+++ /dev/null
-
- This patch is backported from the development SVN and should fix
- bug #1213, which is a deadlock in the SD when a volume is on the
- wrong drive.
-
- Apply it to version 2.4.4 with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-sd-deadlock.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/stored/reserve.c
-===================================================================
---- src/stored/reserve.c (revision 8426)
-+++ src/stored/reserve.c (working copy)
-@@ -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.
-@@ -498,7 +498,6 @@
- void DCR::unreserve_device()
- {
- lock_volumes();
-- dev->dlock();
- if (is_reserved()) {
- clear_reserved();
- reserved_volume = false;
-@@ -514,7 +513,6 @@
- volume_unused(this);
- }
- }
-- dev->dunlock();
- unlock_volumes();
- }
-
-Index: src/stored/acquire.c
-===================================================================
---- src/stored/acquire.c (revision 8426)
-+++ src/stored/acquire.c (working copy)
-@@ -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.
-@@ -647,8 +647,8 @@
-
- /* Detach this dcr only if attached */
- if (dcr->attached_to_dev && dev) {
-+ dev->dlock();
- dcr->unreserve_device();
-- dev->dlock();
- dcr->dev->attached_dcrs->remove(dcr); /* detach dcr from device */
- dcr->attached_to_dev = false;
- // remove_dcr_from_dcrs(dcr); /* remove dcr from jcr list */
+++ /dev/null
-
- This patch fixes bug #1247 - 64-bit time_t and varargs don't get along in some
- printf-like formatting
-
- Apply it to version 2.4.4 with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-time_t_64bit.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/stored/spool.c
-===================================================================
---- src/stored/spool.c (revision 8455)
-+++ src/stored/spool.c (working copy)
-@@ -306,7 +306,7 @@
- set_new_file_parameters(dcr);
-
- /* Subtracting run_time give us elapsed time - wait_time since we started despooling */
-- time_t despool_elapsed = time(NULL) - despool_start - jcr->run_time;
-+ int32_t despool_elapsed = time(NULL) - despool_start - jcr->run_time;
-
- if (despool_elapsed <= 0) {
- despool_elapsed = 1;
-Index: src/stored/append.c
-===================================================================
---- src/stored/append.c (revision 8455)
-+++ src/stored/append.c (working copy)
-@@ -270,7 +270,7 @@
- do_fd_commands(jcr); /* finish dialog with FD */
-
-
-- time_t job_elapsed = time(NULL) - jcr->run_time;
-+ int32_t job_elapsed = time(NULL) - jcr->run_time;
-
- if (job_elapsed <= 0) {
- job_elapsed = 1;
-Index: src/lib/message.c
-===================================================================
---- src/lib/message.c (revision 8455)
-+++ src/lib/message.c (working copy)
-@@ -780,8 +780,8 @@
- case MD_DIRECTOR:
- Dmsg1(850, "DIRECTOR for following msg: %s", msg);
- if (jcr && jcr->dir_bsock && !jcr->dir_bsock->errors) {
-- bnet_fsend(jcr->dir_bsock, "Jmsg Job=%s type=%d level=%d %s",
-- jcr->Job, type, mtime, msg);
-+ bnet_fsend(jcr->dir_bsock, "Jmsg Job=%s type=%d level=%lld %s",
-+ jcr->Job, type, (utime_t)mtime, msg);
- }
- break;
- case MD_STDOUT:
+++ /dev/null
-
- This patch fixes a text sizing problem in the tray-monitor.
- It fixes bug #1219.
-
- Apply it to version 2.4.4 with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-tray-sizing.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/tray-monitor/tray-monitor.c
-===================================================================
---- src/tray-monitor/tray-monitor.c (revision 8393)
-+++ src/tray-monitor/tray-monitor.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2004-2007 Free Software Foundation Europe e.V.
-+ Copyright (C) 2004-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.
-@@ -97,6 +97,7 @@
- static GtkWidget *textview;
- static GtkTextBuffer *buffer;
- static GtkWidget *timeoutspinner;
-+static GtkWidget *scrolledWindow;
- char** xpm_generic_var;
- static gboolean blinkstate = TRUE;
-
-@@ -409,9 +410,13 @@
- }
-
- gtk_box_pack_start(GTK_BOX(vbox), daemon_table, FALSE, FALSE, 0);
--
-+
- textview = gtk_text_view_new();
-
-+ scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
-+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-+ gtk_container_add(GTK_CONTAINER (scrolledWindow), textview);
-+
- buffer = gtk_text_buffer_new(NULL);
-
- gtk_text_buffer_set_text(buffer, "", -1);
-@@ -456,7 +461,7 @@
-
- gtk_text_view_set_buffer(GTK_TEXT_VIEW(textview), buffer);
-
-- gtk_box_pack_start(GTK_BOX(vbox), textview, TRUE, TRUE, 0);
-+ gtk_box_pack_start(GTK_BOX(vbox), scrolledWindow, TRUE, TRUE, 0);
-
- GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
-
+++ /dev/null
-
- This patch is fixes Fix bug #1246 Sometimes access with
- VSS enabled. UCS conversion cache was not properly flushed
- at the end of a Job.
-
- Apply it to version 2.4.4 with:
-
- cd <bacula-source>
- patch -p0 <2.4.4-winvss.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/filed/job.c
-===================================================================
---- src/filed/job.c (revision 8733)
-+++ src/filed/job.c (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2000-2007 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.
-@@ -41,7 +41,7 @@
- #include "vss.h"
-
- static pthread_mutex_t vss_mutex = PTHREAD_MUTEX_INITIALIZER;
--static int enable_vss;
-+static int enable_vss = 0;
- #endif
-
- extern CLIENT *me; /* our client resource */
-@@ -1422,7 +1422,7 @@
- /* inform user about writer states */
- for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++)
- if (g_pVSSClient->GetWriterState(i) < 1) {
-- Jmsg(jcr, M_WARNING, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i));
-+ Jmsg(jcr, M_WARNING, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i));
- jcr->Errors++;
- }
- }
-@@ -1506,6 +1506,7 @@
- Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
- }
- }
-+ Win32ConvCleanupCache();
- V(vss_mutex);
- }
- #endif
-Index: src/win32/Makefile
-===================================================================
---- src/win32/Makefile (revision 8733)
-+++ src/win32/Makefile (working copy)
-@@ -30,7 +30,7 @@
- Makefile.inc: Makefile.inc.in
- @echo Creating $@
- $(ECHO_CMD)TOPDIR=`(cd ../../..;pwd)`; \
-- if test -e ../../../cross-tools/mingw32/bin/mingw32-gcc; then \
-+ if test -e $${TOPDIR}/cross-tools/mingw32/bin/mingw32-gcc; then \
- BINDIR=$${TOPDIR}/cross-tools/mingw32/bin; \
- INCDIR=$${TOPDIR}/cross-tools/mingw32/mingw32/include; \
- DLLDIR=$${TOPDIR}/cross-tools/mingw32/mingw32/bin; \
-@@ -43,7 +43,7 @@
- echo "You must run build-win32-cross-tools and build-dependencies first.\n"; \
- exit 1; \
- fi ; \
-- $(ECHO_CMD)BUILDDIR=`(pwd)`; \
-+ BUILDDIR=`(pwd)`; \
- sed \
- -e "s^@BUILDDIR@^$${BUILDDIR}^" \
- -e "s^@TOPDIR@^$${TOPDIR}^" \
-Index: src/win32/compat/compat.cpp
-===================================================================
---- src/win32/compat/compat.cpp (revision 8733)
-+++ src/win32/compat/compat.cpp (working copy)
-@@ -1,7 +1,7 @@
- /*
- Bacula® - The Network Backup Solution
-
-- Copyright (C) 2004-2008 Free Software Foundation Europe e.V.
-+ Copyright (C) 2004-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.
-@@ -51,8 +51,8 @@
- conversion is called 3 times (lstat, attribs, open),
- by using the cache this is reduced to 1 time */
-
--static POOLMEM *g_pWin32ConvUTF8Cache = get_pool_memory(PM_FNAME);
--static POOLMEM *g_pWin32ConvUCS2Cache = get_pool_memory(PM_FNAME);
-+static POOLMEM *g_pWin32ConvUTF8Cache = NULL;
-+static POOLMEM *g_pWin32ConvUCS2Cache = NULL;
- static DWORD g_dwWin32ConvUTF8strlen = 0;
- static pthread_mutex_t Win32Convmutex = PTHREAD_MUTEX_INITIALIZER;
-
-@@ -69,8 +69,19 @@
- g_pVSSPathConvertW = pPathConvertW;
- }
-
-+static void Win32ConvInitCache()
-+{
-+ if (g_pWin32ConvUTF8Cache) {
-+ return;
-+ }
-+ g_pWin32ConvUTF8Cache = get_pool_memory(PM_FNAME);
-+ g_pWin32ConvUCS2Cache = get_pool_memory(PM_FNAME);
-+}
-+
-+
- void Win32ConvCleanupCache()
- {
-+ P(Win32Convmutex);
- if (g_pWin32ConvUTF8Cache) {
- free_pool_memory(g_pWin32ConvUTF8Cache);
- g_pWin32ConvUTF8Cache = NULL;
-@@ -82,6 +93,7 @@
- }
-
- g_dwWin32ConvUTF8strlen = 0;
-+ V(Win32Convmutex);
- }
-
-
-@@ -451,11 +463,14 @@
- /* if we find the utf8 string in cache, we use the cached ucs2 version.
- we compare the stringlength first (quick check) and then compare the content.
- */
-- if (g_dwWin32ConvUTF8strlen == strlen(pszUTF)) {
-+ if (!g_pWin32ConvUTF8Cache) {
-+ Win32ConvInitCache();
-+ } else if (g_dwWin32ConvUTF8strlen == strlen(pszUTF)) {
- if (bstrcmp(pszUTF, g_pWin32ConvUTF8Cache)) {
-+ /* Return cached value */
- int32_t nBufSize = sizeof_pool_memory(g_pWin32ConvUCS2Cache);
- *pszUCS = check_pool_memory_size(*pszUCS, nBufSize);
-- wcscpy((LPWSTR) *pszUCS, (LPWSTR) g_pWin32ConvUCS2Cache);
-+ wcscpy((LPWSTR) *pszUCS, (LPWSTR)g_pWin32ConvUCS2Cache);
- V(Win32Convmutex);
- return nBufSize / sizeof (WCHAR);
- }
-@@ -477,7 +492,7 @@
- wcscpy((LPWSTR) g_pWin32ConvUCS2Cache, (LPWSTR) *pszUCS);
-
- g_dwWin32ConvUTF8strlen = strlen(pszUTF);
-- g_pWin32ConvUTF8Cache = check_pool_memory_size(g_pWin32ConvUTF8Cache, g_dwWin32ConvUTF8strlen+1);
-+ g_pWin32ConvUTF8Cache = check_pool_memory_size(g_pWin32ConvUTF8Cache, g_dwWin32ConvUTF8strlen+2);
- bstrncpy(g_pWin32ConvUTF8Cache, pszUTF, g_dwWin32ConvUTF8strlen+1);
- V(Win32Convmutex);
-
-Index: src/win32/Makefile.inc.in
-===================================================================
---- src/win32/Makefile.inc.in (revision 8733)
-+++ src/win32/Makefile.inc.in (working copy)
-@@ -11,9 +11,9 @@
-
- BUILDDIR := @BUILDDIR@
- TOPDIR := @TOPDIR@
--DEPKGS := $(TOPDIR)/depkgs-mingw32
-+DEPKGS := @TOPDIR@/depkgs-mingw32
-
--DOCDIR := $(TOPDIR)/docs
-+DOCDIR := @TOPDIR@/docs
- BINDIR := ../release
- LIBDIR := ../release
- OBJDIR := .
+++ /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
-
-
-
+++ /dev/null
-
- This patch can be applied to version 3.0.0. It ensures that the list
- of volumes to be read is created very early when starting the Job in
- the SD (before the drive reservation) so that any Volume to be read
- cannot also be chosen to append.
-
- Apply it to version 3.0.0 with:
-
- cd <bacula-source>
- patch -p0 <3.0.0-read-vol-list.patch
- ./configure <your-options>
- make
- ...
- make install
-
-
-
-Index: src/dird/msgchan.c
-===================================================================
---- src/dird/msgchan.c (revision 8699)
-+++ src/dird/msgchan.c (working copy)
-@@ -144,10 +144,12 @@
- }
- #endif
-
-+static char OKbootstrap[] = "3000 OK bootstrap\n";
-+
- /*
- * Start a job with the Storage daemon
- */
--bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore)
-+bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore, bool send_bsr)
- {
- bool ok = true;
- STORE *storage;
-@@ -196,7 +198,7 @@
- &jcr->VolSessionTime, &auth_key) != 3) {
- Dmsg1(100, "BadJob=%s\n", sd->msg);
- Jmsg(jcr, M_FATAL, 0, _("Storage daemon rejected Job command: %s\n"), sd->msg);
-- return 0;
-+ return false;
- } else {
- jcr->sd_auth_key = bstrdup(auth_key);
- Dmsg1(150, "sd_auth_key=%s\n", jcr->sd_auth_key);
-@@ -204,9 +206,14 @@
- } else {
- Jmsg(jcr, M_FATAL, 0, _("<stored: bad response to Job command: %s\n"),
- sd->bstrerror());
-- return 0;
-+ return false;
- }
-
-+ if (send_bsr && (!send_bootstrap_file(jcr, sd) ||
-+ !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR))) {
-+ return false;
-+ }
-+
- /*
- * We have two loops here. The first comes from the
- * Storage = associated with the Job, and we need
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 8699)
-+++ src/dird/migrate.c (working copy)
-@@ -55,7 +55,6 @@
-
- static const int dbglevel = 10;
-
--static char OKbootstrap[] = "3000 OK bootstrap\n";
- static int get_job_to_migrate(JCR *jcr);
- struct idpkt;
- static bool regex_find_jobids(JCR *jcr, idpkt *ids, const char *query1,
-@@ -353,15 +352,11 @@
- ((STORE *)jcr->rstorage->first())->name());
- return false;
- }
-- if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage)) {
-+ if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /*send_bsr*/true)) {
- return false;
- }
- Dmsg0(150, "Storage daemon connection OK\n");
-
-- if (!send_bootstrap_file(jcr, sd) ||
-- !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
-- return false;
-- }
-
- /*
- * We re-update the job start record so that the start
-Index: src/dird/protos.h
-===================================================================
---- src/dird/protos.h (revision 8699)
-+++ src/dird/protos.h (working copy)
-@@ -155,7 +155,8 @@
- /* msgchan.c */
- extern bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
- int max_retry_time, int verbose);
--extern bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore);
-+extern bool start_storage_daemon_job(JCR *jcr, alist *rstore, alist *wstore,
-+ bool send_bsr=false);
- extern bool start_storage_daemon_message_thread(JCR *jcr);
- extern int bget_dirmsg(BSOCK *bs);
- extern void wait_for_storage_daemon_termination(JCR *jcr);
-Index: src/dird/vbackup.c
-===================================================================
---- src/dird/vbackup.c (revision 8699)
-+++ src/dird/vbackup.c (working copy)
-@@ -50,8 +50,6 @@
-
- static const int dbglevel = 10;
-
--static char OKbootstrap[] = "3000 OK bootstrap\n";
--
- static bool create_bootstrap_file(JCR *jcr, POOLMEM *jobids);
- void vbackup_cleanup(JCR *jcr, int TermCode);
-
-@@ -217,16 +215,11 @@
- /*
- * Now start a job with the Storage daemon
- */
-- if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage)) {
-+ if (!start_storage_daemon_job(jcr, jcr->rstorage, jcr->wstorage, /*send_bsr*/true)) {
- return false;
- }
- Dmsg0(100, "Storage daemon connection OK\n");
-
-- if (!send_bootstrap_file(jcr, sd) ||
-- !response(jcr, sd, OKbootstrap, "Bootstrap", DISPLAY_ERROR)) {
-- return false;
-- }
--
- /*
- * We re-update the job start record so that the start
- * time is set after the run before job. This avoids
-Index: src/stored/fd_cmds.c
-===================================================================
---- src/stored/fd_cmds.c (revision 8699)
-+++ src/stored/fd_cmds.c (working copy)
-@@ -388,6 +388,8 @@
- if (debug_level >= 10) {
- dump_bsr(jcr->bsr, true);
- }
-+ /* If we got a bootstrap, we are reading, so create read volume list */
-+ create_restore_volume_list(jcr);
- ok = true;
-
- bail_out:
-Index: src/stored/read.c
-===================================================================
---- src/stored/read.c (revision 8699)
-+++ src/stored/read.c (working copy)
-@@ -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.
-@@ -62,11 +62,8 @@
- return false;
- }
-
--
-- create_restore_volume_list(jcr);
- if (jcr->NumReadVolumes == 0) {
- Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n"));
-- free_restore_volume_list(jcr);
- fd->fsend(FD_error);
- return false;
- }
-@@ -76,7 +73,6 @@
-
- /* Ready device for reading */
- if (!acquire_device_for_read(dcr)) {
-- free_restore_volume_list(jcr);
- fd->fsend(FD_error);
- return false;
- }
-@@ -92,7 +88,6 @@
- ok = false;
- }
-
-- free_restore_volume_list(jcr);
- Dmsg0(30, "Done reading.\n");
- return ok;
- }
-Index: src/stored/parse_bsr.c
-===================================================================
---- src/stored/parse_bsr.c (revision 8699)
-+++ src/stored/parse_bsr.c (working copy)
-@@ -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.
-Index: src/stored/mac.c
-===================================================================
---- src/stored/mac.c (revision 8699)
-+++ src/stored/mac.c (working copy)
-@@ -84,8 +84,6 @@
- }
- Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr);
-
--
-- create_restore_volume_list(jcr);
- if (jcr->NumReadVolumes == 0) {
- Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
- goto bail_out;
-@@ -161,11 +159,8 @@
- }
- }
-
-- free_restore_volume_list(jcr);
--
- dir_send_job_status(jcr); /* update director */
-
--
- Dmsg0(30, "Done reading.\n");
- jcr->end_time = time(NULL);
- dequeue_messages(jcr); /* send any queued messages */
-Index: src/stored/vol_mgr.c
-===================================================================
---- src/stored/vol_mgr.c (revision 8699)
-+++ src/stored/vol_mgr.c (working copy)
-@@ -529,6 +529,7 @@
- VOLRES vol, *fvol;
-
- if (read_vol_list->empty()) {
-+ Dmsg0(dbglvl, "find_read_vol: read_vol_list empty.\n");
- return NULL;
- }
- /* Do not lock reservations here */
-Index: src/stored/job.c
-===================================================================
---- src/stored/job.c (revision 8699)
-+++ src/stored/job.c (working copy)
-@@ -371,6 +371,8 @@
- free_bsr(jcr->bsr);
- jcr->bsr = NULL;
- }
-+ /* Free any restore volume list created */
-+ free_restore_volume_list(jcr);
- if (jcr->RestoreBootstrap) {
- unlink(jcr->RestoreBootstrap);
- free_pool_memory(jcr->RestoreBootstrap);
-Index: src/stored/acquire.c
-===================================================================
---- src/stored/acquire.c (revision 8699)
-+++ src/stored/acquire.c (working copy)
-@@ -187,7 +187,7 @@
- if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
- Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n",
- dcr->VolumeName, jcr->errmsg);
-- Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
-+ Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
- }
- dev->set_load(); /* set to load volume */
-
-@@ -241,7 +241,7 @@
- * error messages when nothing is mounted.
- */
- if (tape_previously_mounted) {
-- Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
-+ Jmsg(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
- }
- goto default_path;
- case VOL_NAME_ERROR:
-@@ -257,7 +257,7 @@
- dev->set_load();
- /* Fall through */
- default:
-- Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
-+ Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
- default_path:
- Dmsg0(50, "default path\n");
- tape_previously_mounted = 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;
+++ /dev/null
-
-This directory contains patches to the *previous* released version
-of Bacula. As they are developed, they will be put into this directory
-so that they are all in one place, and you can easily find all
-the patches that exist at a particular time.
-
-When a new official version of Bacula is released (for example 1.36.0),
-the patches for the previous release (for example 1.34) will be
-placed in a subdirectory, and patches for the new version will
-go into the main directory.
-
-The file "patches-version" (for example "patches-1.34.6") will
-contain a summary of each of the patches and when it was created,
-so that you can easily see the order and the purpose of each patch.
-Sometimes there may be dependencies between the patches -- i.e. a
-later patch needs a prior patch to be applied first. I'll try to
-note those, but cannot guarantee it.
-
-
-It contains also interesting/experimental patches from users. For examples,
- - SpoolSize defined per job (backup tunning)
- - fix for maxwaittime option
- - new maxschedruntime option
- - etc..
-
-You can find them on testing sub-directory.
+++ /dev/null
-diff -u dvd+rw-tools-5.21.4.10.8/growisofs.c dvd+rw-tools-5.22/growisofs.c
---- dvd+rw-tools-5.21.4.10.8/growisofs.c 2004-08-25 01:02:29.000000000 +0200
-+++ dvd+rw-tools-5.22/growisofs.c 2005-10-16 22:48:02.000000000 +0200
-@@ -315,12 +315,17 @@
- * - Linux: fix for kernel version 2.6>=8, 2.6.8 itself is deficient,
- * but the problem can be worked around by installing this version
- * set-root-uid;
-+ * 5.22: (by Nicolas Boichat, Bacula project)
-+ * - Allow session to cross 4GB boundary regardless of medium type
-+ * (don't need to have a DL media)
-+ * - Add a -F option (used instead of -M or -Z), which displays next_session
-+ * offset and capacity (free space = next_session - capacity).
- */
- #define PRINT_VERSION(cmd) do { \
- char *s=strrchr((cmd),'/'); \
- s ? s++ : (s=(cmd)); \
- printf ("* %.*sgrowisofs by <appro@fy.chalmers.se>,"\
-- " version 5.21,\n",(int)(s-(cmd)),(cmd)); \
-+ " version 5.22,\n",(int)(s-(cmd)),(cmd)); \
- } while (0)
-
- #define _LARGEFILE_SOURCE
-@@ -1720,6 +1725,18 @@
- else in_device = argv[++i];
- dev_found = 'Z';
- }
-+ else if (argv[i][1] == 'F')
-+ { if (len > 2) in_device = argv[i]+2;
-+ else in_device = argv[++i];
-+ dev_found = 'F';
-+ dry_run = 1; /* NEVER write anything with -F */
-+ }
-+ else if (!strncmp(opt,"-free-space",11))
-+ { if (len > 11) in_device = opt+11;
-+ else in_device = argv[++i];
-+ dev_found = 'F';
-+ dry_run = 1; /* NEVER write anything with -F */
-+ }
- else if (!strcmp(opt,"-poor-man"))
- { if (poor_man<0) poor_man = 1;
- continue;
-@@ -1908,7 +1925,9 @@
- fprintf (stderr," you most likely want to use -Z option.\n"),
- exit (FATAL_START(errno));
-
-- if (dev_found == 'M')
-+ if ((dev_found == 'M') ||
-+ ((dev_found == 'F') && !(mmc_profile&0x10000)) && (the_buffer[0] || the_buffer[1] || the_buffer[2]))
-+ /* -F : The medium is not blank, there is a fs on it (the_buffer[0,1 or 2] != 0), so compute next_session. */
- { if (memcmp (the_buffer,"\1CD001",6))
- fprintf (stderr,":-( %s doesn't look like isofs...\n",
- in_device), exit(FATAL_START(EMEDIUMTYPE));
-@@ -1932,7 +1951,7 @@
- exit(FATAL_START(EINVAL));
- }
- else if (next_session > (0x200000-0x5000)) /* 4GB/2K-40MB/2K */
-- if ((mmc_profile&0xFFFF)!=0x2B || !no_4gb_check)
-+ if (!no_4gb_check)
- fprintf (stderr,":-( next session would cross 4GB "
- "boundary, aborting...\n"),
- exit (FATAL_START(ENOSPC));
-@@ -1974,7 +1993,7 @@
- exit (FATAL_START(EINVAL));
-
- if (imgfd<0)
-- { if (mkisofs_argc==1)
-+ { if ((mkisofs_argc==1) && (dev_found != 'F'))
- fprintf (stderr,"%s: no mkisofs options specified, "
- "aborting...\n",argv[0]),
- exit (FATAL_START(EINVAL));
-@@ -2114,6 +2133,15 @@
- }
- }
-
-+ if (dev_found == 'F') {
-+ off64_t capacity = 0;
-+ printf("next_session=%lld\n", next_session*CD_BLOCK);
-+ if (ioctl_handle!=INVALID_HANDLE)
-+ capacity = get_capacity (ioctl_handle);
-+ printf("capacity=%lld\n", capacity);
-+ exit(0);
-+ }
-+
- if (imgfd>=0)
- { quiet--;
- if (builtin_dd (imgfd,out_fd,next_session*CD_BLOCK) < 0)
+++ /dev/null
---- dvd+rw-tools-6.1.old/growisofs.c 2006-01-26 22:16:54.000000000 +0100
-+++ dvd+rw-tools-6.1/growisofs.c 2006-02-15 00:00:44.000000000 +0100
-@@ -355,12 +355,17 @@
- * - Treat only x73xx OPC errors as fatal;
- * - Fix typo in -speed scaling code;
- * - permit tracksize to be not divisible by 32KB in DAO mode;
-+ * 6.1.1: (by Nicolas Boichat, Bacula project)
-+ * - Allow session to cross 4GB boundary regardless of medium type
-+ * (don't need to have a DL media)
-+ * - Add a -F option (used instead of -M or -Z), which displays next_session
-+ * offset and capacity (free space = next_session - capacity).
- */
- #define PRINT_VERSION(cmd) do { \
- char *s=strrchr((cmd),'/'); \
- s ? s++ : (s=(cmd)); \
- printf ("* %.*sgrowisofs by <appro@fy.chalmers.se>,"\
-- " version 6.1,\n",(int)(s-(cmd)),(cmd)); \
-+ " version 6.1.1,\n",(int)(s-(cmd)),(cmd)); \
- } while (0)
- \f
- #define _LARGEFILE_SOURCE
-@@ -2329,6 +2334,18 @@
- else in_device = argv[++i];
- dev_found = 'Z';
- }
-+ else if (argv[i][1] == 'F')
-+ { if (len > 2) in_device = argv[i]+2;
-+ else in_device = argv[++i];
-+ dev_found = 'F';
-+ dry_run = 1; /* NEVER write anything with -F */
-+ }
-+ else if (!strncmp(opt,"-free-space",11))
-+ { if (len > 11) in_device = opt+11;
-+ else in_device = argv[++i];
-+ dev_found = 'F';
-+ dry_run = 1; /* NEVER write anything with -F */
-+ }
- else if (!strcmp(opt,"-poor-man"))
- { if (poor_man<0) poor_man = 1;
- continue;
-@@ -2542,7 +2559,9 @@
- fprintf (stderr," you most likely want to use -Z option.\n"),
- exit (FATAL_START(errno));
-
-- if (dev_found == 'M')
-+ if ((dev_found == 'M') ||
-+ ((dev_found == 'F') && !(mmc_profile&0x10000)) && (saved_descriptors[0].type[0] || saved_descriptors[0].type[1] || saved_descriptors[0].type[2]))
-+ /* -F : The medium is not blank, there is a fs on it (the_buffer[0,1 or 2] != 0), so compute next_session. */
- { if (memcmp (saved_descriptors[0].type,"\1CD001",6))
- fprintf (stderr,":-( %s doesn't look like isofs...\n",
- in_device), exit(FATAL_START(EMEDIUMTYPE));
-@@ -2565,7 +2584,7 @@
- exit(FATAL_START(EINVAL));
- }
- else if (next_session > (0x200000-0x5000)) /* 4GB/2K-40MB/2K */
-- if ((mmc_profile&0xFFFF)!=0x2B || !no_4gb_check)
-+ if (!no_4gb_check)
- fprintf (stderr,":-( next session would cross 4GB "
- "boundary, aborting...\n"),
- exit (FATAL_START(ENOSPC));
-@@ -2608,7 +2627,7 @@
- exit (FATAL_START(EINVAL));
-
- if (imgfd<0)
-- { if (mkisofs_argc==1)
-+ { if ((mkisofs_argc==1) && (dev_found != 'F'))
- fprintf (stderr,"%s: no mkisofs options specified, "
- "aborting...\n",argv[0]),
- exit (FATAL_START(EINVAL));
-@@ -2880,6 +2899,15 @@
- }
- }
-
-+ if (dev_found == 'F') {
-+ off64_t capacity = 0;
-+ printf("next_session=%lld\n", next_session*CD_BLOCK);
-+ if (ioctl_handle!=INVALID_HANDLE)
-+ capacity = get_capacity (ioctl_handle);
-+ printf("capacity=%lld\n", capacity);
-+ exit(0);
-+ }
-+
- if (imgfd>=0)
- { quiet--;
- if (builtin_dd (imgfd,out_fd,next_session*CD_BLOCK) < 0)
+++ /dev/null
-Index: src/baconfig.h
-===================================================================
---- src/baconfig.h (révision 6953)
-+++ src/baconfig.h (copie de travail)
-@@ -38,6 +38,7 @@
-
- /* Bacula common configuration defines */
-
-+#define USE_FAKETAPE 1
- #undef TRUE
- #undef FALSE
- #define TRUE 1
-@@ -106,11 +107,21 @@
- #define CATS_IMP_EXP
-
- #define OSDependentInit()
--#define tape_open open
--#define tape_ioctl ioctl
--#define tape_read ::read
--#define tape_write ::write
--#define tape_close ::close
-+#if defined(USE_FAKETAPE)
-+# define tape_open faketape_open
-+# define tape_ioctl faketape_ioctl
-+# define tape_read faketape_read
-+# define tape_write faketape_write
-+# define tape_close faketape_close
-+# define IS_TAPE(x) S_ISREG(x)
-+#else /* UNIX && !FAKETAPE */
-+# define tape_open ::open
-+# define tape_ioctl ::ioctl
-+# define tape_read ::read
-+# define tape_write ::write
-+# define tape_close ::close
-+# define IS_TAPE(x) S_ISCHR(x)
-+#endif
-
- #endif
-
-Index: src/stored/Makefile.in
-===================================================================
---- src/stored/Makefile.in (révision 6953)
-+++ src/stored/Makefile.in (copie de travail)
-@@ -20,7 +20,7 @@
- dummy:
-
- # bacula-sd
--SDOBJS = stored.o ansi_label.o \
-+SDOBJS = stored.o ansi_label.o faketape.o \
- autochanger.o acquire.o append.o \
- askdir.o authenticate.o \
- block.o butil.o dev.o \
-@@ -31,7 +31,7 @@
- spool.o status.o stored_conf.o wait.o
-
- # btape
--TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o \
-+TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o faketape.o \
- lock.o ansi_label.o dvd.o ebcdic.o \
- autochanger.o acquire.o mount.o record.o read_record.o \
- reserve.o \
-@@ -39,26 +39,26 @@
-
- # bls
- BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \
-- ansi_label.o dvd.o ebcdic.o lock.o \
-+ ansi_label.o dvd.o ebcdic.o lock.o faketape.o \
- autochanger.o acquire.o mount.o parse_bsr.o record.o \
- read_record.o reserve.o scan.o stored_conf.o spool.o wait.o
-
- # bextract
- BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
-- ansi_label.o dvd.o ebcdic.o lock.o \
-+ ansi_label.o dvd.o ebcdic.o lock.o faketape.o \
- autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
- pythonsd.o read_record.o reserve.o \
- scan.o stored_conf.o spool.o wait.o
-
- # bscan
- SCNOBJS = bscan.o block.o device.o dev.o label.o \
-- ansi_label.o dvd.o ebcdic.o lock.o \
-+ ansi_label.o dvd.o ebcdic.o lock.o faketape.o \
- autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
- butil.o read_record.o scan.o reserve.o stored_conf.o spool.o wait.o
-
- # bcopy
- COPYOBJS = bcopy.o block.o device.o dev.o label.o \
-- ansi_label.o dvd.o ebcdic.o lock.o \
-+ ansi_label.o dvd.o ebcdic.o lock.o faketape.o \
- autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
- butil.o read_record.o reserve.o \
- scan.o stored_conf.o spool.o wait.o
-Index: src/stored/stored.h
-===================================================================
---- src/stored/stored.h (révision 6953)
-+++ src/stored/stored.h (copie de travail)
-@@ -78,6 +78,10 @@
- int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
- #endif
-
-+#ifdef USE_FAKETAPE
-+# include "faketape.h"
-+#endif
-+
- /* Daemon globals from stored.c */
- extern STORES *me; /* "Global" daemon resource */
- extern bool forge_on; /* proceed inspite of I/O errors */
-Index: src/stored/dev.c
-===================================================================
---- src/stored/dev.c (révision 6953)
-+++ src/stored/dev.c (copie de travail)
-@@ -123,7 +123,7 @@
- }
- if (S_ISDIR(statp.st_mode)) {
- device->dev_type = B_FILE_DEV;
-- } else if (S_ISCHR(statp.st_mode)) {
-+ } else if (IS_TAPE(statp.st_mode)) { /* char device or fake tape */
- device->dev_type = B_TAPE_DEV;
- } else if (S_ISFIFO(statp.st_mode)) {
- device->dev_type = B_FIFO_DEV;
-@@ -379,7 +379,7 @@
- /* If busy retry each second for max_open_wait seconds */
- for ( ;; ) {
- /* Try non-blocking open */
-- m_fd = ::open(dev_name, mode+O_NONBLOCK);
-+ m_fd = tape_open(dev_name, mode+O_NONBLOCK);
- if (m_fd < 0) {
- berrno be;
- dev_errno = errno;
-@@ -391,10 +391,10 @@
- mt_com.mt_op = MTREW;
- mt_com.mt_count = 1;
- /* rewind only if dev is a tape */
-- if (is_tape() && (ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
-+ if (is_tape() && (tape_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0)) {
- berrno be;
- dev_errno = errno; /* set error status from rewind */
-- ::close(m_fd);
-+ tape_close(m_fd);
- clear_opened();
- Dmsg2(100, "Rewind error on %s close: ERR=%s\n", print_name(),
- be.bstrerror(dev_errno));
-@@ -404,8 +404,8 @@
- }
- } else {
- /* Got fd and rewind worked, so we must have medium in drive */
-- ::close(m_fd);
-- m_fd = ::open(dev_name, mode); /* open normally */
-+ tape_close(m_fd);
-+ m_fd = tape_open(dev_name, mode); /* open normally */
- if (m_fd < 0) {
- berrno be;
- dev_errno = errno;
-@@ -2490,7 +2490,7 @@
- } else {
- neof = 1;
- }
-- if (ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
-+ if (tape_ioctl(dev->fd(), MTIOCSETEOTMODEL, (caddr_t)&neof) < 0) {
- berrno be;
- dev->dev_errno = errno; /* save errno */
- Mmsg2(dev->errmsg, _("Unable to set eotmodel on device %s: ERR=%s\n"),
+++ /dev/null
-Index: src/cats/sql.c
-===================================================================
---- src/cats/sql.c (révision 7344)
-+++ src/cats/sql.c (copie de travail)
-@@ -635,5 +635,43 @@
- return;
- }
-
-+/*
-+ * Open a new connexion to mdb catalog. This function is used
-+ * by batch and accurate mode.
-+ */
-+bool db_open_batch_connexion(JCR *jcr, B_DB *mdb)
-+{
-+ int multi_db=false;
-
-+#ifdef HAVE_BATCH_FILE_INSERT
-+ multi_db=true; /* we force a new connexion only if batch insert is enabled */
-+#endif
-+
-+ if (!jcr->db_batch) {
-+ jcr->db_batch = db_init_database(jcr,
-+ mdb->db_name,
-+ mdb->db_user,
-+ mdb->db_password,
-+ mdb->db_address,
-+ mdb->db_port,
-+ mdb->db_socket,
-+ multi_db /* multi_db = true when using batch mode */);
-+ if (!jcr->db_batch) {
-+ Jmsg0(jcr, M_FATAL, 0, "Could not init batch connexion");
-+ return false;
-+ }
-+
-+ if (!db_open_database(jcr, jcr->db_batch)) {
-+ Mmsg2(&jcr->db_batch->errmsg, _("Could not open database \"%s\": ERR=%s\n"),
-+ jcr->db_batch->db_name, db_strerror(jcr->db_batch));
-+ Jmsg1(jcr, M_FATAL, 0, "%s", jcr->db_batch->errmsg);
-+ return false;
-+ }
-+ Dmsg3(100, "initdb ref=%d connected=%d db=%p\n", jcr->db_batch->ref_count,
-+ jcr->db_batch->connected, jcr->db_batch->db);
-+
-+ }
-+ return true;
-+}
-+
- #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_SQLITE || HAVE_POSTGRESQL*/
-Index: src/cats/protos.h
-===================================================================
---- src/cats/protos.h (révision 7344)
-+++ src/cats/protos.h (copie de travail)
-@@ -49,6 +49,7 @@
- int mult_db_connections);
- int db_open_database(JCR *jcr, B_DB *db);
- void db_close_database(JCR *jcr, B_DB *db);
-+bool db_open_batch_connexion(JCR *jcr, B_DB *mdb);
- void db_escape_string(JCR *jcr, B_DB *db, char *snew, char *old, int len);
- char *db_strerror(B_DB *mdb);
- int db_next_index(JCR *jcr, B_DB *mdb, char *table, char *index);
-Index: src/cats/sql_create.c
-===================================================================
---- src/cats/sql_create.c (révision 7344)
-+++ src/cats/sql_create.c (copie de travail)
-@@ -758,7 +758,7 @@
- {
- int JobStatus = jcr->JobStatus;
-
-- if (!jcr->db_batch) { /* no files to backup ? */
-+ if (!jcr->batch_started) { /* no files to backup ? */
- Dmsg0(50,"db_create_file_record : no files\n");
- return true;
- }
-@@ -845,38 +845,19 @@
- Dmsg1(dbglevel, "Fname=%s\n", ar->fname);
- Dmsg0(dbglevel, "put_file_into_catalog\n");
-
-- if (!jcr->db_batch) {
-- Dmsg2(100, "Opendb attr. Stream=%d fname=%s\n", ar->Stream, ar->fname);
-- jcr->db_batch = db_init_database(jcr,
-- mdb->db_name,
-- mdb->db_user,
-- mdb->db_password,
-- mdb->db_address,
-- mdb->db_port,
-- mdb->db_socket,
-- 1 /* multi_db = true */);
-- if (!jcr->db_batch) {
-- Mmsg1(&mdb->errmsg, _("Could not init batch database: \"%s\".\n"),
-- jcr->db->db_name);
-- Jmsg1(jcr, M_FATAL, 0, "%s", mdb->errmsg);
-- return false;
-- }
-+ /* Open the dedicated connexion */
-+ if (!jcr->batch_started) {
-
-- if (!db_open_database(jcr, jcr->db_batch)) {
-- Mmsg2(&mdb->errmsg, _("Could not open database \"%s\": ERR=%s\n"),
-- jcr->db->db_name, db_strerror(jcr->db_batch));
-- Jmsg1(jcr, M_FATAL, 0, "%s", mdb->errmsg);
-+ if (!db_open_batch_connexion(jcr, mdb)) {
- return false;
-- }
--
-+ }
- if (!sql_batch_start(jcr, jcr->db_batch)) {
- Mmsg1(&mdb->errmsg,
- "Can't start batch mode: ERR=%s", db_strerror(jcr->db_batch));
- Jmsg1(jcr, M_FATAL, 0, "%s", mdb->errmsg);
- return false;
- }
-- Dmsg3(100, "initdb ref=%d connected=%d db=%p\n", jcr->db_batch->ref_count,
-- jcr->db_batch->connected, jcr->db_batch->db);
-+ jcr->batch_started = true;
- }
- B_DB *bdb = jcr->db_batch;
-
-@@ -895,12 +876,12 @@
-
-
- /*
-- if (bdb->changes > 100000) {
-- db_write_batch_file_records(jcr);
-- bdb->changes = 0;
-- sql_batch_start(jcr, bdb);
-- }
--*/
-+ * if (bdb->changes > 100000) {
-+ * db_write_batch_file_records(jcr);
-+ * bdb->changes = 0;
-+ * sql_batch_start(jcr, bdb);
-+ * }
-+ */
-
- return sql_batch_insert(jcr, bdb, ar);
- }
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (révision 7344)
-+++ src/jcr.h (copie de travail)
-@@ -226,7 +226,8 @@
- bool cached_attribute; /* set if attribute is cached */
- POOLMEM *attr; /* Attribute string from SD */
- B_DB *db; /* database pointer */
-- B_DB *db_batch; /* database pointer for batch insert */
-+ B_DB *db_batch; /* database pointer for batch and accurate */
-+ bool batch_started; /* is batch mode already started ? */
- ATTR_DBR *ar; /* DB attribute record */
- guid_list *id_list; /* User/group id to name list */
- bool accurate; /* true if job is accurate */
-
-Index: src/dird/backup.c
-===================================================================
---- src/dird/backup.c (révision 7344)
-+++ src/dird/backup.c (copie de travail)
-@@ -133,6 +133,7 @@
- return true;
- }
- POOLMEM *jobids = get_pool_memory(PM_FNAME);
-+
- db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
-
- if (*jobids == 0) {
-@@ -150,13 +151,19 @@
- Dmsg2(200, "jobids=%s nb=%s\n", jobids, nb);
- jcr->file_bsock->fsend("accurate files=%s\n", nb);
-
-- db_get_file_list(jcr, jcr->db, jobids, accurate_list_handler, (void *)jcr);
-+ 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);
-+
-+ /* TODO: close the batch connexion ? (can be used very soon) */
-+
- free_pool_memory(jobids);
- free_pool_memory(nb);
-
- jcr->file_bsock->signal(BNET_EOD);
-- /* TODO: use response() ? */
-
- return true;
- }
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (révision 7344)
-+++ src/dird/job.c (copie de travail)
-@@ -960,10 +960,10 @@
- pthread_cond_destroy(&jcr->term_wait);
- jcr->term_wait_inited = false;
- }
-- if (jcr->db_batch && jcr->db_batch != jcr->db) {
-+ if (jcr->db_batch) {
- db_close_database(jcr, jcr->db_batch);
-+ jcr->db_batch = NULL;
- }
-- jcr->db_batch = NULL;
- if (jcr->db) {
- db_close_database(jcr, jcr->db);
- jcr->db = NULL;
+++ /dev/null
-Index: src/filed/accurate.c
-===================================================================
---- src/filed/accurate.c (révision 7351)
-+++ src/filed/accurate.c (copie de travail)
-@@ -32,193 +32,311 @@
-
- #include "bacula.h"
- #include "filed.h"
-+#include "lib/htable.h"
-+static int dbglvl=500;
-
--static int dbglvl=200;
-+#ifdef USE_DB
-+#include <db.h>
-
--typedef struct PrivateCurFile {
--#ifndef USE_TCADB
-- hlink link;
--#endif
-- char *fname; /* not stored with tchdb mode */
-- time_t ctime;
-- time_t mtime;
-- bool seen;
--} CurFile;
--
--#ifdef USE_TCADB
--static void realfree(void *p); /* used by tokyo code */
--
- /*
-- * Update hash element seen=1
-+ * This backend uses DB Berkeley
- */
--static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
-+class AccurateBackendDB : public AccurateBackend
- {
-- bool ret=true;
-+public:
-+ ~AccurateBackendDB() { destroy(); }
-+ bool init(JCR *jcr, int nb_elt);
-+ void destroy();
-
-- elt->seen = 1;
-- if (!tcadbput(jcr->file_list,
-- elt->fname, strlen(elt->fname)+1,
-- elt, sizeof(CurFile)))
-- { /* TODO: disabling accurate mode ? */
-- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk\n"));
-- ret = false;
-+ bool insert(JCR *jcr, char *key, CurFile *item);
-+ bool lookup(JCR *jcr, char *key, CurFile *item);
-+
-+ bool mark_as_seen(JCR *jcr, char *key, CurFile *item);
-+
-+ CurFile *first(CurFile *elt);
-+ CurFile *next();
-+ void finish();
-+private:
-+ DB *db; /* DB object */
-+ DB_ENV *dbenv; /* DB Env object */
-+ DBC *cursorp; /* DB cursor */
-+ DBT dbkey;
-+ DBT dbdata;
-+ POOLMEM *hash_name; /* file name for hash */
-+ bool first_pass;
-+};
-+
-+void AccurateBackendDB::destroy()
-+{
-+ /* cleanup walk cursor if any */
-+ if (cursorp) {
-+ cursorp->c_close(cursorp);
-+ cursorp = NULL;
- }
--
-- return ret;
-+ if (db) {
-+ db->close(db, DB_NOSYNC);
-+ db = NULL;
-+ }
-+ if (dbenv) {
-+ dbenv->dbremove(dbenv, NULL, hash_name, NULL, 0);
-+ dbenv->close(dbenv, 0);
-+ dbenv = NULL;
-+ }
-+ if (hash_name) {
-+ unlink(hash_name); /* remove the hash on disk */
-+ free_pool_memory(hash_name);
-+ hash_name = NULL;
-+ }
- }
-
--static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
-+bool AccurateBackendDB::init(JCR *jcr, int nb_elt)
- {
-- bool found=false;
-- ret->seen = 0;
-- int size;
-- CurFile *elt;
-+ int ret;
-+
-+ Dmsg0(dbglvl, "init DB accurate backend\n");
-
-- elt = (CurFile*)tcadbget(jcr->file_list,
-- fname, strlen(fname)+1, &size);
-- if (elt)
-+ if ((ret = db_env_create(&dbenv, 0)) != 0) {
-+ Jmsg(jcr, M_ERROR, 1, _("Can't open initialize hash disk ERR=%i\n"), ret);
-+ return false;
-+ }
-+
-+ dbenv->set_cachesize(dbenv, 0, 256 * 1024 * 1024, 0);
-+ dbenv->set_errfile(dbenv, stderr);
-+ dbenv->set_errpfx(dbenv, "hash");
-+
-+ int flags = DB_PRIVATE | DB_INIT_MPOOL | DB_CREATE | DB_THREAD;
-+ if ((ret = dbenv->open(dbenv, working_directory, flags, 0)) != 0) {
-+ destroy();
-+ Jmsg(jcr, M_ERROR, 1, _("Can't open initialize hash disk ERR=%i\n"), ret);
-+ return false;
-+ }
-+
-+ dbenv->set_flags(dbenv, DB_TXN_NOSYNC, 1);
-+
-+ if ((ret = db_create(&db, dbenv, 0)) != 0) {
-+ destroy();
-+ Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk ERR=%i\n"), ret);
-+ return false;
-+ }
-+
-+ hash_name = get_pool_memory(PM_MESSAGE);
-+ make_unique_filename(&hash_name, jcr->JobId, "accurate");
-+
-+ if ((ret = db->open(db,
-+ NULL, hash_name, NULL,
-+ DB_BTREE, DB_CREATE, 0600)) != 0)
- {
-- /* TODO: don't malloc/free results */
-- found = true;
-- elt->fname = fname;
-- memcpy(ret, elt, sizeof(CurFile));
-- realfree(elt);
--// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
-+ destroy();
-+ Jmsg(jcr, M_ERROR, 1, _("Can't setup hash disk ERR=%i\n"), ret);
-+ return false;
- }
-- return found;
-+
-+ first_pass=0;
-+
-+ return true;
- }
-
--/* Create tokyo dbm hash file
-- * If something goes wrong, we cancel accurate mode.
-- */
--static bool accurate_init(JCR *jcr, int nbfile)
-+/* Just update the element->seen to know if we have seen it */
-+bool AccurateBackendDB::mark_as_seen(JCR *jcr, char *key, CurFile *item)
- {
-- jcr->file_list = tcadbnew();
--//
--// tchdbsetcache(jcr->file_list, 300000);
--// tchdbtune(jcr->file_list,
--// nbfile, /* nb bucket 0.5n to 4n */
--// 6, /* size of element 2^x */
--// 16,
--// 0); /* options like compression */
--//
-- jcr->hash_name = get_pool_memory(PM_MESSAGE);
-- POOLMEM *temp = get_pool_memory(PM_MESSAGE);
-+ item->seen = 1;
-+ return insert(jcr, key, item);
-+}
-
-- if (nbfile > 500000) {
-- make_unique_filename(&jcr->hash_name, jcr->JobId, "accurate");
-- pm_strcat(jcr->hash_name, ".tcb");
-- Mmsg(temp, "%s#bnum=%i#mode=e#opts=l",
-- jcr->hash_name, nbfile*4);
-- Dmsg1(dbglvl, "Doing accurate hash on disk %s\n", jcr->hash_name);
-- } else {
-- Dmsg0(dbglvl, "Doing accurate hash on memory\n");
-- pm_strcpy(jcr->hash_name, "*");
-- pm_strcpy(temp, "*");
-+/* insert/replace */
-+bool AccurateBackendDB::insert(JCR *jcr, char *key, CurFile *item)
-+{
-+ int ret;
-+ memset(&dbkey, 0, sizeof(DBT));
-+ memset(&dbdata, 0, sizeof(DBT));
-+ dbkey.data = key;
-+ dbkey.size = strlen(key)+1;
-+ dbdata.data = item;
-+ dbdata.size = sizeof(CurFile);
-+ if ((ret = db->put(db, NULL, &dbkey, &dbdata, 0))) {
-+ Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%i\n"), ret);
-+ return false;
- }
-+ return true;
-+}
-+
-+bool AccurateBackendDB::lookup(JCR *jcr, char *key, CurFile *item)
-+{
-+ int ret=false;
-+
-+ /* Zero out the DBTs before using them. */
-+ memset(&dbkey, 0, sizeof(DBT));
-+ memset(&dbdata, 0, sizeof(DBT));
-+
-+ dbkey.data = key;
-+ dbkey.size = strlen(key)+1;
-
-- if(!tcadbopen(jcr->file_list, jcr->hash_name)){
-- Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk\n"));
-- Jmsg(jcr, M_INFO, 1, _("Disabling accurate mode\n"));
-- tcadbdel(jcr->file_list);
-- jcr->file_list = NULL;
-- jcr->accurate = false;
-+ dbdata.data = item;
-+ dbdata.ulen = sizeof(CurFile);
-+ dbdata.flags = DB_DBT_USERMEM;
-+
-+ if (db->get(db, NULL, &dbkey, &dbdata, 0) == 0) {
-+ ret=true;
- }
-- free_pool_memory(temp);
-- return jcr->file_list != NULL;
-+ item->fname = key;
-+ return ret;
- }
-
--/* This function is called at the end of backup
-- * We walk over all hash disk element, and we check
-- * for elt.seen.
-+/*
-+ * We use user memory to copy data
- */
--bool accurate_send_deleted_list(JCR *jcr)
-+CurFile *AccurateBackendDB::first(CurFile *elt)
- {
-- char *key;
-+ /* Zero out the DBTs before using them. */
-+ memset(&dbkey, 0, sizeof(DBT));
-+ memset(&dbdata, 0, sizeof(DBT));
-+ dbdata.data = elt;
-+ dbdata.ulen = sizeof(CurFile);
-+ dbdata.flags = DB_DBT_USERMEM;
-+ db->cursor(db, NULL, &cursorp, 0);
-+ return next();
-+}
-+
-+CurFile *AccurateBackendDB::next()
-+{
- CurFile *elt;
-- int size;
-- FF_PKT *ff_pkt;
-- int stream = STREAM_UNIX_ATTRIBUTES;
--
-- if (!jcr->accurate || jcr->JobLevel == L_FULL) {
-- goto bail_out;
-+ if (cursorp->c_get(cursorp, &dbkey, &dbdata, DB_NEXT) == 0) {
-+ /* update fname field with fresh data */
-+ elt = (CurFile *)dbdata.data;
-+ elt->fname = (char *)dbkey.data;
-+ return elt;
-+ } else {
-+ return NULL;
- }
-+}
-
-- if (jcr->file_list == NULL) {
-- goto bail_out;
-+void AccurateBackendDB::finish()
-+{
-+ if (cursorp) {
-+ cursorp->c_close(cursorp);
-+ cursorp = NULL;
- }
-+}
-
-- ff_pkt = init_find_files();
-- ff_pkt->type = FT_DELETED;
-+#endif /* USE_DB */
-
-- /* traverse records */
-- tcadbiterinit(jcr->file_list);
-- while((key = tcadbiternext2(jcr->file_list)) != NULL) {
-- elt = (CurFile *) tcadbget(jcr->file_list,
-- key, strlen(key)+1, &size);
-- if (elt)
-- {
-- if (!elt->seen) { /* already seen */
-- ff_pkt->fname = key;
-- ff_pkt->statp.st_mtime = elt->mtime;
-- ff_pkt->statp.st_ctime = elt->ctime;
-- encode_and_send_attributes(jcr, ff_pkt, stream);
-- }
-- realfree(elt);
-- }
-- realfree(key); /* tokyo cabinet have to use real free() */
-- }
-+/****************************************************************/
-
-- term_find_files(ff_pkt);
--bail_out:
-- /* TODO: clean htable when this function is not reached ? */
-- if (jcr->file_list) {
-- if(!tcadbclose(jcr->file_list)){
-- Jmsg(jcr, M_ERROR, 1, _("Can't close accurate hash disk\n"));
-- }
-+/*
-+ * This is the htable implementation for accurate mode
-+ */
-+class AccurateBackendHT : public AccurateBackend
-+{
-+public:
-+ ~AccurateBackendHT() { destroy(); }
-+ bool init(JCR *jcr, int nb_elt);
-+ void destroy();
-
-- /* delete the object */
-- tcadbdel(jcr->file_list);
-- if (!bstrcmp(jcr->hash_name, "*")) {
-- unlink(jcr->hash_name);
-- }
-+ bool insert(JCR *jcr, char *key, CurFile *item);
-+ bool lookup(JCR *jcr, char *key, CurFile *item);
-
-- free_pool_memory(jcr->hash_name);
-- jcr->hash_name = NULL;
-- jcr->file_list = NULL;
-+ bool mark_as_seen(JCR *jcr, char *key, CurFile *item);
-+
-+ CurFile *first(CurFile *elt);
-+ CurFile *next();
-+ void finish();
-+private:
-+ htable *db;
-+};
-+
-+typedef struct {
-+ CurFile elt;
-+ hlink link; /* need this for htable link */
-+} HTCurFile;
-+
-+void AccurateBackendHT::destroy()
-+{
-+ if (db) {
-+ db->destroy();
-+ free(db);
-+ db = NULL;
- }
-+}
-+
-+bool AccurateBackendHT::init(JCR *jcr, int nb_elt)
-+{
-+ Dmsg0(dbglvl, "init HT accurate backend\n");
-+
-+ HTCurFile *elt=NULL;
-+ db = (htable *)malloc(sizeof(htable));
-+ db->init(elt, &elt->link, nb_elt);
- return true;
- }
-
--#else /* HTABLE mode */
-+bool AccurateBackendHT::insert(JCR *jcr, char *key, CurFile *item)
-+{
-+ /* alloc CurFile + hlink + fname */
-+ HTCurFile *htf = (HTCurFile *)db->hash_malloc(sizeof(HTCurFile)+strlen(key)+1);
-+ memcpy(&htf->elt, item, sizeof(CurFile));
-
--static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
-+ /* store fname at the end of the struct */
-+ htf->elt.fname = (char *) htf + sizeof(HTCurFile);
-+
-+ strcpy(htf->elt.fname, key);
-+ db->insert(htf->elt.fname, htf);
-+ return true;
-+}
-+
-+bool AccurateBackendHT::mark_as_seen(JCR *jcr, char *key, CurFile *item)
- {
-- CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
-- temp->seen = 1; /* records are in memory */
-+ HTCurFile *temp = (HTCurFile *)db->lookup(key);
-+ if (temp) {
-+ temp->elt.seen = 1; /* update in memory */
-+ }
- return true;
- }
-
--static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
-+bool AccurateBackendHT::lookup(JCR *jcr, char *key, CurFile *item)
- {
- bool found=false;
-- ret->seen = 0;
-
-- CurFile *temp = (CurFile *)jcr->file_list->lookup(fname);
-+ HTCurFile *temp = (HTCurFile *)db->lookup(key);
- if (temp) {
-- memcpy(ret, temp, sizeof(CurFile));
-+ memcpy(item, &temp->elt, sizeof(CurFile));
- found=true;
--// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
- }
--
- return found;
- }
-
-+CurFile *AccurateBackendHT::first(CurFile *elt)
-+{
-+ HTCurFile *temp = (HTCurFile *)db->first();
-+ return &temp->elt;
-+}
-+
-+CurFile *AccurateBackendHT::next()
-+{
-+ HTCurFile *temp = (HTCurFile *)db->next();
-+ return &temp->elt;
-+}
-+
-+void AccurateBackendHT::finish()
-+{
-+}
-+
-+/****************************************************************/
-+
-+/* Create hash file
-+ * For less than 1M files, use htable in memory
-+ */
- static bool accurate_init(JCR *jcr, int nbfile)
- {
-- CurFile *elt=NULL;
-- jcr->file_list = (htable *)malloc(sizeof(htable));
-- jcr->file_list->init(elt, &elt->link, nbfile);
-+#ifdef USE_DB
-+ if (nbfile > 1000000) {
-+ jcr->file_list = New(AccurateBackendDB);
-+ } else {
-+ jcr->file_list = New(AccurateBackendHT);
-+ }
-+#else
-+ jcr->file_list = New(AccurateBackendHT);
-+#endif
-+ jcr->file_list->init(jcr, nbfile);
-+
- return true;
- }
-
-@@ -228,7 +346,8 @@
- */
- bool accurate_send_deleted_list(JCR *jcr)
- {
-- CurFile *elt;
-+ CurFile elt;
-+ CurFile *item;
- FF_PKT *ff_pkt;
- int stream = STREAM_UNIX_ATTRIBUTES;
-
-@@ -242,31 +361,28 @@
-
- ff_pkt = init_find_files();
- ff_pkt->type = FT_DELETED;
--
-- foreach_htable (elt, jcr->file_list) {
-- if (!elt->seen) { /* already seen */
-- Dmsg2(dbglvl, "deleted fname=%s seen=%i\n", elt->fname, elt->seen);
-- ff_pkt->fname = elt->fname;
-- ff_pkt->statp.st_mtime = elt->mtime;
-- ff_pkt->statp.st_ctime = elt->ctime;
-+
-+ for (item = jcr->file_list->first(&elt); item ; item = jcr->file_list->next()) {
-+ if (!item->seen) { /* already seen */
-+ Dmsg2(dbglvl, "deleted fname=%s seen=%i\n", item->fname, item->seen);
-+ ff_pkt->fname = item->fname;
-+ ff_pkt->statp.st_mtime = item->mtime;
-+ ff_pkt->statp.st_ctime = item->ctime;
- encode_and_send_attributes(jcr, ff_pkt, stream);
- }
--// free(elt->fname);
- }
-+ jcr->file_list->finish();
-
- term_find_files(ff_pkt);
- bail_out:
- /* TODO: clean htable when this function is not reached ? */
- if (jcr->file_list) {
-- jcr->file_list->destroy();
-- free(jcr->file_list);
-+ delete jcr->file_list;
- jcr->file_list = NULL;
- }
- return true;
- }
-
--#endif /* common code */
--
- static bool accurate_add_file(JCR *jcr, char *fname, char *lstat)
- {
- bool ret = true;
-@@ -278,25 +394,12 @@
- elt.mtime = statp.st_mtime;
- elt.seen = 0;
-
--#ifdef USE_TCADB
-- if (!tcadbput(jcr->file_list,
-- fname, strlen(fname)+1,
-- &elt, sizeof(CurFile)))
-- {
-- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%s\n"));
-+ if (!jcr->file_list->insert(jcr, fname, &elt)) {
-+ Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash ERR=%s\n"));
- ret = false;
- }
--#else /* HTABLE */
-- CurFile *item;
-- /* we store CurFile, fname and ctime/mtime in the same chunk */
-- item = (CurFile *)jcr->file_list->hash_malloc(sizeof(CurFile)+strlen(fname)+1);
-- memcpy(item, &elt, sizeof(CurFile));
-- item->fname = (char *)item+sizeof(CurFile);
-- strcpy(item->fname, fname);
-- jcr->file_list->insert(item->fname, item);
--#endif
-
--// Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
-+ Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
- return ret;
- }
-
-@@ -324,7 +427,7 @@
- fname = ff_pkt->fname;
- }
-
-- if (!accurate_lookup(jcr, fname, &elt)) {
-+ if (!jcr->file_list->lookup(jcr, fname, &elt)) {
- Dmsg1(dbglvl, "accurate %s (not found)\n", fname);
- stat = true;
- goto bail_out;
-@@ -343,7 +446,7 @@
- stat = true;
- }
-
-- accurate_mark_file_as_seen(jcr, &elt);
-+ jcr->file_list->mark_as_seen(jcr, fname, &elt);
- Dmsg2(dbglvl, "accurate %s = %i\n", fname, stat);
-
- bail_out:
-@@ -379,7 +482,7 @@
- while (dir->recv() >= 0) {
- len = strlen(dir->msg) + 1;
- if (len < dir->msglen) {
-- accurate_add_file(jcr, dir->msg, dir->msg + len);
-+ accurate_add_file(jcr, dir->msg, dir->msg + len);
- }
- }
-
-@@ -398,17 +501,3 @@
-
- return true;
- }
--
--#ifdef USE_TCADB
--
--/*
-- * Tokyo Cabinet library doesn't use smartalloc by default
-- * results need to be released with real free()
-- */
--#undef free
--void realfree(void *p)
--{
-- free(p);
--}
--
--#endif
-Index: src/filed/filed.h
-===================================================================
---- src/filed/filed.h (révision 7351)
-+++ src/filed/filed.h (copie de travail)
-@@ -35,11 +35,35 @@
-
-
- #define FILE_DAEMON 1
--#ifdef USE_TCADB /* hash disk based */
--# include <tcadb.h>
--#else
--# include "lib/htable.h"
--#endif
-+
-+/*
-+ * Used to store accurate information
-+ */
-+typedef struct {
-+ char *fname;
-+ time_t ctime;
-+ time_t mtime;
-+ bool seen;
-+} CurFile;
-+
-+/*
-+ * Virtual class for accurate backend (libdb or htable)
-+ */
-+class AccurateBackend: public SMARTALLOC
-+{
-+public:
-+ AccurateBackend() : SMARTALLOC() {}
-+ virtual ~AccurateBackend() {}
-+ virtual bool init(JCR *jcr, int nb_elt) = 0;
-+ virtual bool insert(JCR *jcr, char *key, CurFile *item) = 0;
-+ virtual bool lookup(JCR *jcr, char *key, CurFile *item) = 0;
-+ virtual bool mark_as_seen(JCR *jcr, char *key, CurFile *item) = 0;
-+ virtual CurFile *first(CurFile *elt) = 0;
-+ virtual CurFile *next() = 0;
-+ virtual void finish() = 0;
-+ virtual void destroy() {}
-+};
-+
- #include "filed_conf.h"
- #include "fd_plugins.h"
- #include "findlib/find.h"
-Index: src/baconfig.h
-===================================================================
---- src/baconfig.h (révision 7351)
-+++ src/baconfig.h (copie de travail)
-@@ -113,6 +113,12 @@
-
- #endif /* HAVE_WIN32 */
-
-+/* Select db backend for accurate mode */
-+#ifndef USE_TCADB
-+# ifndef USE_DB
-+# define USE_HTABLE
-+# endif
-+#endif
-
- #ifdef ENABLE_NLS
- #include <libintl.h>
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (révision 7351)
-+++ src/jcr.h (copie de travail)
-@@ -341,12 +341,7 @@
- CRYPTO_CTX crypto; /* Crypto ctx */
- DIRRES* director; /* Director resource */
- bool VSS; /* VSS used by FD */
--#ifdef USE_TCADB
-- TCADB *file_list; /* Previous file list (accurate mode) */
-- POOLMEM *hash_name;
--#else
-- htable *file_list; /* Previous file list (accurate mode) */
--#endif
-+ AccurateBackend *file_list; /* Accurate backend store */
- #endif /* FILE_DAEMON */
-
-
+++ /dev/null
-Index: src/filed/accurate.c
-===================================================================
---- src/filed/accurate.c (revision 7619)
-+++ src/filed/accurate.c (working copy)
-@@ -36,25 +36,17 @@
- static int dbglvl=200;
-
- typedef struct PrivateCurFile {
-- rblink link;
-+ hlink link;
- char *fname;
- time_t ctime;
- time_t mtime;
- bool seen;
- } CurFile;
-
--static int my_cmp(void *item1, void *item2)
--{
-- CurFile *elt1, *elt2;
-- elt1 = (CurFile *) item1;
-- elt2 = (CurFile *) item2;
-- return strcmp(elt1->fname, elt2->fname);
--}
--
- static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
- {
- /* TODO: just use elt->seen = 1 */
-- CurFile *temp = (CurFile *)jcr->file_list->search(elt, my_cmp);
-+ CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
- if (temp) {
- temp->seen = 1; /* records are in memory */
- }
-@@ -66,9 +58,7 @@
- bool found=false;
- ret->seen = 0;
-
-- CurFile search;
-- search.fname = fname;
-- CurFile *temp = (CurFile *)jcr->file_list->search(&search, my_cmp);
-+ CurFile *temp = (CurFile *)jcr->file_list->lookup(fname);
- if (temp) {
- memcpy(ret, temp, sizeof(CurFile));
- found=true;
-@@ -81,7 +71,8 @@
- static bool accurate_init(JCR *jcr, int nbfile)
- {
- CurFile *elt = NULL;
-- jcr->file_list = New(rblist(elt, &elt->link));
-+ jcr->file_list = (htable *)malloc(sizeof(htable));
-+ jcr->file_list->init(elt, &elt->link, nbfile);
- return true;
- }
-
-@@ -106,7 +97,7 @@
- ff_pkt = init_find_files();
- ff_pkt->type = FT_DELETED;
-
-- foreach_rblist(elt, jcr->file_list) {
-+ foreach_htable(elt, jcr->file_list) {
- if (!elt->seen) { /* already seen */
- // Dmsg2(dbglvl, "deleted fname=%s seen=%i\n", elt->fname, elt->seen);
- ff_pkt->fname = elt->fname;
-@@ -121,7 +112,8 @@
- bail_out:
- /* TODO: clean htable when this function is not reached ? */
- if (jcr->file_list) {
-- delete jcr->file_list;
-+ jcr->file_list->destroy();
-+ free(jcr->file_list);
- jcr->file_list = NULL;
- }
- return true;
-@@ -140,11 +132,11 @@
-
- CurFile *item;
- /* we store CurFile, fname and ctime/mtime in the same chunk */
-- item = (CurFile *)malloc(sizeof(CurFile)+strlen(fname)+1);
-+ item = (CurFile *)jcr->file_list->hash_malloc(sizeof(CurFile)+strlen(fname)+1);
- memcpy(item, &elt, sizeof(CurFile));
- item->fname = (char *)item+sizeof(CurFile);
- strcpy(item->fname, fname);
-- jcr->file_list->insert(item, my_cmp);
-+ jcr->file_list->insert(item->fname, item);
-
- // Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
- return ret;
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (revision 7619)
-+++ src/jcr.h (working copy)
-@@ -350,7 +350,7 @@
- CRYPTO_CTX crypto; /* Crypto ctx */
- DIRRES* director; /* Director resource */
- bool VSS; /* VSS used by FD */
-- rblist *file_list; /* Previous file list (accurate mode) */
-+ htable *file_list; /* Previous file list (accurate mode) */
- #endif /* FILE_DAEMON */
-
-
+++ /dev/null
-Index: src/filed/accurate.c
-===================================================================
---- src/filed/accurate.c (revision 7617)
-+++ src/filed/accurate.c (working copy)
-@@ -33,182 +33,46 @@
- #include "bacula.h"
- #include "filed.h"
-
--static int dbglvl=200;
-+static int dbglvl=2;
-
- typedef struct PrivateCurFile {
--#ifndef USE_TCADB
-- hlink link;
--#endif
-- char *fname; /* not stored with tchdb mode */
-+ rblink link;
-+ char *fname;
- time_t ctime;
- time_t mtime;
- bool seen;
- } CurFile;
-
--#ifdef USE_TCADB
--static void realfree(void *p); /* used by tokyo code */
--
--/*
-- * Update hash element seen=1
-- */
--static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
-+static int my_cmp(void *item1, void *item2)
- {
-- bool ret=true;
--
-- elt->seen = 1;
-- if (!tcadbput(jcr->file_list,
-- elt->fname, strlen(elt->fname)+1,
-- elt, sizeof(CurFile)))
-- { /* TODO: disabling accurate mode ? */
-- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk\n"));
-- ret = false;
-- }
--
-- return ret;
-+ CurFile *elt1, *elt2;
-+ elt1 = (CurFile *) item1;
-+ elt2 = (CurFile *) item2;
-+ return strcmp(elt1->fname, elt2->fname);
- }
-
--static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
-+static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
- {
-- bool found=false;
-- ret->seen = 0;
-- int size;
-- CurFile *elt;
--
-- elt = (CurFile*)tcadbget(jcr->file_list,
-- fname, strlen(fname)+1, &size);
-- if (elt)
-- {
-- /* TODO: don't malloc/free results */
-- found = true;
-- elt->fname = fname;
-- memcpy(ret, elt, sizeof(CurFile));
-- realfree(elt);
--// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
-+ /* TODO: just use elt->seen = 1 */
-+ CurFile *temp = (CurFile *)jcr->file_list->search(elt, my_cmp);
-+ if (temp) {
-+ temp->seen = 1; /* records are in memory */
- }
-- return found;
--}
--
--/* Create tokyo dbm hash file
-- * If something goes wrong, we cancel accurate mode.
-- */
--static bool accurate_init(JCR *jcr, int nbfile)
--{
-- jcr->file_list = tcadbnew();
--//
--// tchdbsetcache(jcr->file_list, 300000);
--// tchdbtune(jcr->file_list,
--// nbfile, /* nb bucket 0.5n to 4n */
--// 6, /* size of element 2^x */
--// 16,
--// 0); /* options like compression */
--//
-- jcr->hash_name = get_pool_memory(PM_MESSAGE);
-- POOLMEM *temp = get_pool_memory(PM_MESSAGE);
--
-- if (nbfile > 500000) {
-- make_unique_filename(&jcr->hash_name, jcr->JobId, "accurate");
-- pm_strcat(jcr->hash_name, ".tcb");
-- Mmsg(temp, "%s#bnum=%i#mode=e#opts=l",
-- jcr->hash_name, nbfile*4);
-- Dmsg1(dbglvl, "Doing accurate hash on disk %s\n", jcr->hash_name);
-- } else {
-- Dmsg0(dbglvl, "Doing accurate hash on memory\n");
-- pm_strcpy(jcr->hash_name, "*");
-- pm_strcpy(temp, "*");
-- }
--
-- if(!tcadbopen(jcr->file_list, jcr->hash_name)){
-- Jmsg(jcr, M_ERROR, 1, _("Can't open accurate hash disk\n"));
-- Jmsg(jcr, M_INFO, 1, _("Disabling accurate mode\n"));
-- tcadbdel(jcr->file_list);
-- jcr->file_list = NULL;
-- jcr->accurate = false;
-- }
-- free_pool_memory(temp);
-- return jcr->file_list != NULL;
--}
--
--/* This function is called at the end of backup
-- * We walk over all hash disk element, and we check
-- * for elt.seen.
-- */
--bool accurate_send_deleted_list(JCR *jcr)
--{
-- char *key;
-- CurFile *elt;
-- int size;
-- FF_PKT *ff_pkt;
-- int stream = STREAM_UNIX_ATTRIBUTES;
--
-- if (!jcr->accurate || jcr->get_JobLevel() == L_FULL) {
-- goto bail_out;
-- }
--
-- if (jcr->file_list == NULL) {
-- goto bail_out;
-- }
--
-- ff_pkt = init_find_files();
-- ff_pkt->type = FT_DELETED;
--
-- /* traverse records */
-- tcadbiterinit(jcr->file_list);
-- while((key = tcadbiternext2(jcr->file_list)) != NULL) {
-- elt = (CurFile *) tcadbget(jcr->file_list,
-- key, strlen(key)+1, &size);
-- if (elt)
-- {
-- if (!elt->seen) { /* already seen */
-- ff_pkt->fname = key;
-- ff_pkt->statp.st_mtime = elt->mtime;
-- ff_pkt->statp.st_ctime = elt->ctime;
-- encode_and_send_attributes(jcr, ff_pkt, stream);
-- }
-- realfree(elt);
-- }
-- realfree(key); /* tokyo cabinet have to use real free() */
-- }
--
-- term_find_files(ff_pkt);
--bail_out:
-- /* TODO: clean htable when this function is not reached ? */
-- if (jcr->file_list) {
-- if(!tcadbclose(jcr->file_list)){
-- Jmsg(jcr, M_ERROR, 1, _("Can't close accurate hash disk\n"));
-- }
--
-- /* delete the object */
-- tcadbdel(jcr->file_list);
-- if (!bstrcmp(jcr->hash_name, "*")) {
-- unlink(jcr->hash_name);
-- }
--
-- free_pool_memory(jcr->hash_name);
-- jcr->hash_name = NULL;
-- jcr->file_list = NULL;
-- }
- return true;
- }
-
--#else /* HTABLE mode */
--
--static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
--{
-- CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
-- temp->seen = 1; /* records are in memory */
-- return true;
--}
--
- static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
- {
- bool found=false;
- ret->seen = 0;
-
-- CurFile *temp = (CurFile *)jcr->file_list->lookup(fname);
-+ CurFile search;
-+ search.fname = fname;
-+ CurFile *temp = (CurFile *)jcr->file_list->search(&search, my_cmp);
- if (temp) {
- memcpy(ret, temp, sizeof(CurFile));
- found=true;
--// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
-+ Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
- }
-
- return found;
-@@ -217,8 +81,7 @@
- static bool accurate_init(JCR *jcr, int nbfile)
- {
- CurFile *elt = NULL;
-- jcr->file_list = (htable *)malloc(sizeof(htable));
-- jcr->file_list->init(elt, &elt->link, nbfile);
-+ jcr->file_list = New(rblist(elt, &elt->link));
- return true;
- }
-
-@@ -243,7 +106,7 @@
- ff_pkt = init_find_files();
- ff_pkt->type = FT_DELETED;
-
-- foreach_htable(elt, jcr->file_list) {
-+ foreach_rblist(elt, jcr->file_list) {
- if (!elt->seen) { /* already seen */
- Dmsg2(dbglvl, "deleted fname=%s seen=%i\n", elt->fname, elt->seen);
- ff_pkt->fname = elt->fname;
-@@ -258,15 +121,12 @@
- bail_out:
- /* TODO: clean htable when this function is not reached ? */
- if (jcr->file_list) {
-- jcr->file_list->destroy();
-- free(jcr->file_list);
-+ delete jcr->file_list;
- jcr->file_list = NULL;
- }
- return true;
- }
-
--#endif /* common code */
--
- static bool accurate_add_file(JCR *jcr, char *fname, char *lstat)
- {
- bool ret = true;
-@@ -278,25 +138,15 @@
- elt.mtime = statp.st_mtime;
- elt.seen = 0;
-
--#ifdef USE_TCADB
-- if (!tcadbput(jcr->file_list,
-- fname, strlen(fname)+1,
-- &elt, sizeof(CurFile)))
-- {
-- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%s\n"));
-- ret = false;
-- }
--#else /* HTABLE */
- CurFile *item;
- /* we store CurFile, fname and ctime/mtime in the same chunk */
-- item = (CurFile *)jcr->file_list->hash_malloc(sizeof(CurFile)+strlen(fname)+1);
-+ item = (CurFile *)malloc(sizeof(CurFile)+strlen(fname)+1);
- memcpy(item, &elt, sizeof(CurFile));
- item->fname = (char *)item+sizeof(CurFile);
- strcpy(item->fname, fname);
-- jcr->file_list->insert(item->fname, item);
--#endif
-+ jcr->file_list->insert(item, my_cmp);
-
--// Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
-+ Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
- return ret;
- }
-
-@@ -399,17 +249,3 @@
-
- return true;
- }
--
--#ifdef USE_TCADB
--
--/*
-- * Tokyo Cabinet library doesn't use smartalloc by default
-- * results need to be released with real free()
-- */
--#undef free
--void realfree(void *p)
--{
-- free(p);
--}
--
--#endif
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (revision 7618)
-+++ src/jcr.h (working copy)
-@@ -350,12 +350,7 @@
- CRYPTO_CTX crypto; /* Crypto ctx */
- DIRRES* director; /* Director resource */
- bool VSS; /* VSS used by FD */
--#ifdef USE_TCADB
-- TCADB *file_list; /* Previous file list (accurate mode) */
-- POOLMEM *hash_name;
--#else
-- htable *file_list; /* Previous file list (accurate mode) */
--#endif
-+ rblist *file_list; /* Previous file list (accurate mode) */
- #endif /* FILE_DAEMON */
-
-
+++ /dev/null
-Index: src/filed/Makefile.in
-===================================================================
---- src/filed/Makefile.in (révision 6991)
-+++ src/filed/Makefile.in (copie de travail)
-@@ -7,6 +7,7 @@
- @MCOMMON@
-
- srcdir = .
-+libdir = ../lib
- VPATH = .
- .PATH: .
-
-@@ -55,7 +56,7 @@
- # inference rules
- .c.o:
- @echo "Compiling $<"
-- $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $<
-+ $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) -I$(libdir) $(CFLAGS) $<
- #-------------------------------------------------------------------------
- all: Makefile @WIN32@ bacula-fd @STATIC_FD@
- @echo "==== Make of filed is good ===="
-@@ -78,15 +79,15 @@
- (cd win32; $(MAKE) DESTDIR=$(DESTDIR))
- @rm -f bacula-fd.exe
-
--bacula-fd: $(SVROBJS) ../findlib/libfind.a ../lib/libbac.a @WIN32@
-+bacula-fd: $(SVROBJS) ../findlib/libfind.a ../lib/libbac.a ../lib/libtokyocabinet.a @WIN32@
- @echo "Linking $@ ..."
- $(CXX) $(WLDFLAGS) $(LDFLAGS) -L../lib -L../findlib -o $@ $(SVROBJS) \
-- $(WIN32LIBS) $(FDLIBS) -lfind -lbac -lm $(PYTHON_LIBS) $(LIBS) \
-+ $(WIN32LIBS) $(FDLIBS) -lfind -lbac -ltokyocabinet -lm $(PYTHON_LIBS) $(LIBS) \
- $(DLIB) $(WRAPLIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
-
- static-bacula-fd: $(SVROBJS) ../findlib/libfind.a ../lib/libbac.a @WIN32@
- $(CXX) $(WLDFLAGS) $(LDFLAGS) -static -L../lib -L../findlib -o $@ $(SVROBJS) \
-- $(WIN32LIBS) $(FDLIBS) -lfind -lbac -lm $(PYTHON_LIBS) $(LIBS) \
-+ $(WIN32LIBS) $(FDLIBS) -lfind -lbac -ltokyodbm -lm $(PYTHON_LIBS) $(LIBS) \
- $(DLIB) $(WRAPLIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
- strip $@
-
-@@ -152,7 +153,7 @@
- @$(MV) Makefile Makefile.bak
- @$(SED) "/^# DO NOT DELETE:/,$$ d" Makefile.bak > Makefile
- @$(ECHO) "# DO NOT DELETE: nice dependency list follows" >> Makefile
-- @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(SQL_INC) *.c >> Makefile
-+ @$(CXX) -S -M $(CPPFLAGS) $(XINC) $(PYTHON_INC) -I$(srcdir) -I$(basedir) -I$(libdir) *.c >> Makefile
- @if test -f Makefile ; then \
- $(RMF) Makefile.bak; \
- else \
-Index: src/filed/accurate.c
-===================================================================
---- src/filed/accurate.c (révision 6991)
-+++ src/filed/accurate.c (copie de travail)
-@@ -36,16 +36,12 @@
- static int dbglvl=200;
-
- typedef struct PrivateCurFile {
--#ifndef USE_TCADB
-- hlink link;
--#endif
- char *fname; /* not stored with tchdb mode */
- time_t ctime;
- time_t mtime;
- bool seen;
- } CurFile;
-
--#ifdef USE_TCADB
- static void realfree(void *p); /* used by tokyo code */
-
- /*
-@@ -190,83 +186,6 @@
- return true;
- }
-
--#else /* HTABLE mode */
--
--static bool accurate_mark_file_as_seen(JCR *jcr, CurFile *elt)
--{
-- CurFile *temp = (CurFile *)jcr->file_list->lookup(elt->fname);
-- temp->seen = 1; /* records are in memory */
-- return true;
--}
--
--static bool accurate_lookup(JCR *jcr, char *fname, CurFile *ret)
--{
-- bool found=false;
-- ret->seen = 0;
--
-- CurFile *temp = (CurFile *)jcr->file_list->lookup(fname);
-- if (temp) {
-- memcpy(ret, temp, sizeof(CurFile));
-- found=true;
--// Dmsg1(dbglvl, "lookup <%s> ok\n", fname);
-- }
--
-- return found;
--}
--
--static bool accurate_init(JCR *jcr, int nbfile)
--{
-- CurFile *elt=NULL;
-- jcr->file_list = (htable *)malloc(sizeof(htable));
-- jcr->file_list->init(elt, &elt->link, nbfile);
-- return true;
--}
--
--/* This function is called at the end of backup
-- * We walk over all hash disk element, and we check
-- * for elt.seen.
-- */
--bool accurate_send_deleted_list(JCR *jcr)
--{
-- CurFile *elt;
-- FF_PKT *ff_pkt;
-- int stream = STREAM_UNIX_ATTRIBUTES;
--
-- if (!jcr->accurate || jcr->JobLevel == L_FULL) {
-- goto bail_out;
-- }
--
-- if (jcr->file_list == NULL) {
-- goto bail_out;
-- }
--
-- ff_pkt = init_find_files();
-- ff_pkt->type = FT_DELETED;
--
-- foreach_htable (elt, jcr->file_list) {
-- if (!elt->seen) { /* already seen */
-- Dmsg2(dbglvl, "deleted fname=%s seen=%i\n", elt->fname, elt->seen);
-- ff_pkt->fname = elt->fname;
-- ff_pkt->statp.st_mtime = elt->mtime;
-- ff_pkt->statp.st_ctime = elt->ctime;
-- encode_and_send_attributes(jcr, ff_pkt, stream);
-- }
--// free(elt->fname);
-- }
--
-- term_find_files(ff_pkt);
--bail_out:
-- /* TODO: clean htable when this function is not reached ? */
-- if (jcr->file_list) {
-- jcr->file_list->destroy();
-- free(jcr->file_list);
-- jcr->file_list = NULL;
-- }
-- return true;
--}
--
--#endif /* common code */
--
- static bool accurate_add_file(JCR *jcr, char *fname, char *lstat)
- {
- bool ret = true;
-@@ -278,7 +197,6 @@
- elt.mtime = statp.st_mtime;
- elt.seen = 0;
-
--#ifdef USE_TCADB
- if (!tcadbput(jcr->file_list,
- fname, strlen(fname)+1,
- &elt, sizeof(CurFile)))
-@@ -286,15 +204,6 @@
- Jmsg(jcr, M_ERROR, 1, _("Can't update accurate hash disk ERR=%s\n"));
- ret = false;
- }
--#else /* HTABLE */
-- CurFile *item;
-- /* we store CurFile, fname and ctime/mtime in the same chunk */
-- item = (CurFile *)jcr->file_list->hash_malloc(sizeof(CurFile)+strlen(fname)+1);
-- memcpy(item, &elt, sizeof(CurFile));
-- item->fname = (char *)item+sizeof(CurFile);
-- strcpy(item->fname, fname);
-- jcr->file_list->insert(item->fname, item);
--#endif
-
- // Dmsg2(dbglvl, "add fname=<%s> lstat=%s\n", fname, lstat);
- return ret;
-@@ -399,8 +308,6 @@
- return true;
- }
-
--#ifdef USE_TCADB
--
- /*
- * Tokyo Cabinet library doesn't use smartalloc by default
- * results need to be released with real free()
-@@ -411,4 +318,3 @@
- free(p);
- }
-
--#endif
-Index: src/filed/filed.h
-===================================================================
---- src/filed/filed.h (révision 6991)
-+++ src/filed/filed.h (copie de travail)
-@@ -35,11 +35,7 @@
-
-
- #define FILE_DAEMON 1
--#ifdef USE_TCADB /* hash disk based */
--# include <tcadb.h>
--#else
--# include "lib/htable.h"
--#endif
-+#include "lib/tcadb.h"
- #include "filed_conf.h"
- #include "fd_plugins.h"
- #include "findlib/find.h"
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (révision 6991)
-+++ src/jcr.h (copie de travail)
-@@ -341,12 +341,8 @@
- CRYPTO_CTX crypto; /* Crypto ctx */
- DIRRES* director; /* Director resource */
- bool VSS; /* VSS used by FD */
--#ifdef USE_TCADB
- TCADB *file_list; /* Previous file list (accurate mode) */
- POOLMEM *hash_name;
--#else
-- htable *file_list; /* Previous file list (accurate mode) */
--#endif
- #endif /* FILE_DAEMON */
-
-
-Index: src/lib/Makefile.in
-===================================================================
---- src/lib/Makefile.in (révision 6993)
-+++ src/lib/Makefile.in (copie de travail)
-@@ -47,7 +47,6 @@
-
- EXTRAOBJS = @OBJLIST@
-
--
- .SUFFIXES: .c .o .ch .dvi .pdf .tex .view .w .1
- .PHONY:
- .DONTCARE:
-@@ -62,10 +61,17 @@
- $(NO_ECHO)$(CXX) $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) $(PYTHON_INC) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $<
-
- #-------------------------------------------------------------------------
--all: Makefile libbac.a
-+all: Makefile libbac.a libtokyocabinet.a
- @echo "==== Make of lib is good ===="
- @echo " "
-
-+libtokyocabinet.a:
-+ @(cd tokyocabinet ; echo "==>Entering directory `pwd`"; \
-+ $(MAKE) $@ || (echo ""; echo ""; echo " ====== Error in `pwd` ======"; \
-+ echo ""; echo "";));
-+ @cp tokyocabinet/tcadb.h tokyocabinet/tcbdb.h tokyocabinet/tchdb.h .
-+ @cp tokyocabinet/libtokyocabinet.a .
-+
- libbac.a: $(LIBOBJS)
- @echo "Making $@ ..."
- $(AR) rc $@ $(LIBOBJS)
-@@ -113,7 +119,7 @@
- @echo "Compiling $<"
- $(NO_ECHO)$(CXX) -fPIC $(DEFS) $(DEBUG) -c $(WCFLAGS) $(CPPFLAGS) -I$(srcdir) -I$(basedir) $(DINCLUDE) $(CFLAGS) $<
-
--
-+
- install:
-
- uninstall:
-@@ -121,6 +127,7 @@
- clean:
- $(RMF) *.a core a.out *.o *.bak *.tex *.pdf *~ *.intpro *.extpro 1 2 3
- $(RMF) rwlock_test md5sum sha1sum
-+ (cd tokyocabinet ; make clean)
-
- realclean: clean
- $(RMF) tags
+++ /dev/null
-Index: src/cats/sql.c
-===================================================================
---- src/cats/sql.c (révision 5461)
-+++ src/cats/sql.c (copie de travail)
-@@ -111,7 +111,8 @@
- /* Check that the tables correspond to the version we want */
- bool check_tables_version(JCR *jcr, B_DB *mdb)
- {
-- const char *query = "SELECT VersionId FROM Version";
-+ const char *query = "SELECT VersionId FROM Version "
-+ " WHERE Product = 'bacula'";
-
- bacula_db_version = 0;
- if (!db_sql_query(mdb, query, int_handler, (void *)&bacula_db_version)) {
-Index: src/cats/update_postgresql_tables.in
-===================================================================
---- src/cats/update_postgresql_tables.in (révision 5461)
-+++ src/cats/update_postgresql_tables.in (copie de travail)
-@@ -1,10 +1,10 @@
- #!/bin/sh
- #
--# Shell script to update PostgreSQL tables from version 1.38 to 2.0.0 or higher
-+# Shell script to update PostgreSQL tables from version 2.2 to 3 or higher
- #
- echo " "
--echo "This script will update a Bacula PostgreSQL database from version 9 to 10"
--echo " which is needed to convert from Bacula version 1.38.x to 2.0.0 or higher"
-+echo "This script will update a Bacula PostgreSQL database from version 10 to 11"
-+echo " which is needed to convert from Bacula version 2.2 to 3 or higher"
- echo "Depending on the size of your database,"
- echo "this script may take several minutes to run."
- echo " "
-@@ -13,65 +13,10 @@
-
- if $bindir/psql -f - -d ${db_name} $* <<END-OF-DATA
-
--ALTER TABLE media ADD COLUMN DeviceId integer;
--UPDATE media SET DeviceId=0;
--ALTER TABLE media ADD COLUMN MediaTypeId integer;
--UPDATE media SET MediaTypeId=0;
--ALTER TABLE media ADD COLUMN LocationId integer;
--UPDATE media SET LocationId=0;
--ALTER TABLE media ADD COLUMN RecycleCount integer;
--UPDATE media SET RecycleCount=0;
--ALTER TABLE media ADD COLUMN InitialWrite timestamp without time zone;
--ALTER TABLE media ADD COLUMN scratchpoolid integer;
--UPDATE media SET scratchpoolid=0;
--ALTER TABLE media ADD COLUMN recyclepoolid integer;
--UPDATE media SET recyclepoolid=0;
--ALTER TABLE media ADD COLUMN enabled integer;
--UPDATE media SET enabled=1;
--ALTER TABLE media ADD COLUMN Comment TEXT;
-+ALTER TABLE version ADD COLUMN product char(8);
-
--ALTER TABLE job ADD COLUMN RealEndTime timestamp without time zone;
--ALTER TABLE job ADD COLUMN PriorJobId integer;
--UPDATE job SET PriorJobId=0;
--
--ALTER TABLE jobmedia DROP COLUMN Stripe;
--
--CREATE TABLE Location (
-- LocationId SERIAL NOT NULL,
-- Location TEXT NOT NULL,
-- Cost integer default 0,
-- Enabled integer,
-- PRIMARY KEY (LocationId)
--);
--
--CREATE TABLE LocationLog (
-- LocLogId SERIAL NOT NULL,
-- Date timestamp without time zone,
-- Comment TEXT NOT NULL,
-- MediaId INTEGER DEFAULT 0,
-- LocationId INTEGER DEFAULT 0,
-- newvolstatus text not null
-- check (newvolstatus in ('Full','Archive','Append',
-- 'Recycle','Purged','Read-Only','Disabled',
-- 'Error','Busy','Used','Cleaning','Scratch')),
-- newenabled smallint,
-- PRIMARY KEY(LocLogId)
--);
--
--
--CREATE TABLE Log
--(
-- LogId serial not null,
-- JobId integer not null,
-- Time timestamp without time zone,
-- LogText text not null,
-- primary key (LogId)
--);
--create index log_name_idx on Log (JobId);
--
--
- DELETE FROM version;
--INSERT INTO version (versionId) VALUES (10);
-+INSERT INTO version (product, versionId) VALUES ('bacula', 11);
-
- vacuum;
-
-Index: src/cats/make_sqlite3_tables.in
-===================================================================
---- src/cats/make_sqlite3_tables.in (révision 5461)
-+++ src/cats/make_sqlite3_tables.in (copie de travail)
-@@ -283,6 +283,7 @@
- INSERT INTO NextId (id, TableName) VALUES (1, "Job");
-
- CREATE TABLE Version (
-+ Product CHAR(8),
- VersionId INTEGER UNSIGNED NOT NULL
- );
-
-@@ -350,7 +351,7 @@
-
-
- -- Initialize Version
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (Product, VersionId) VALUES ('bacula', 11);
-
-
- PRAGMA default_cache_size = 100000;
-Index: src/cats/update_sqlite3_tables.in
-===================================================================
---- src/cats/update_sqlite3_tables.in (révision 5461)
-+++ src/cats/update_sqlite3_tables.in (copie de travail)
-@@ -1,10 +1,10 @@
- #!/bin/sh
- #
--# shell script to update SQLite from version 1.38 to 2.0
-+# shell script to update SQLite from version 2.2 to 3
- #
- echo " "
--echo "This script will update a Bacula SQLite database from version 9 to 10"
--echo " which is needed to convert from Bacula version 1.38.x to 2.0.x or higher"
-+echo "This script will update a Bacula SQLite database from version 10 to 11"
-+echo " which is needed to convert from Bacula version 2.2 to 3 or higher"
- echo "Depending on the size of your database,"
- echo "this script may take several minutes to run."
- echo " "
-@@ -17,236 +17,15 @@
- ${bindir}/${sqlite} $* ${db_name}.db <<END-OF-DATA
- BEGIN TRANSACTION;
-
--CREATE TEMPORARY TABLE Media_backup (
-- MediaId INTEGER UNSIGNED AUTOINCREMENT,
-- VolumeName VARCHAR(128) NOT NULL,
-- Slot INTEGER DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- MediaType VARCHAR(128) NOT NULL,
-- MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0,
-- LabelType TINYINT DEFAULT 0,
-- FirstWritten DATETIME DEFAULT 0,
-- LastWritten DATETIME DEFAULT 0,
-- LabelDate DATETIME DEFAULT 0,
-- VolJobs INTEGER UNSIGNED DEFAULT 0,
-- VolFiles INTEGER UNSIGNED DEFAULT 0,
-- VolBlocks INTEGER UNSIGNED DEFAULT 0,
-- VolMounts INTEGER UNSIGNED DEFAULT 0,
-- VolBytes BIGINT UNSIGNED DEFAULT 0,
-- VolParts INTEGER UNSIGNED DEFAULT 0,
-- VolErrors INTEGER UNSIGNED DEFAULT 0,
-- VolWrites INTEGER UNSIGNED DEFAULT 0,
-- VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
-- VolStatus VARCHAR(20) NOT NULL,
-- Enabled TINYINT DEFAULT 1,
-- Recycle TINYINT DEFAULT 0,
-- VolRetention BIGINT UNSIGNED DEFAULT 0,
-- VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-- MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-- MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-- MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-- InChanger TINYINT DEFAULT 0,
-- StorageId INTEGER UNSIGNED REFERENCES Storage,
-- DeviceId INTEGER UNSIGNED REFERENCES Device,
-- MediaAddressing TINYINT DEFAULT 0,
-- VolReadTime BIGINT UNSIGNED DEFAULT 0,
-- VolWriteTime BIGINT UNSIGNED DEFAULT 0,
-- EndFile INTEGER UNSIGNED DEFAULT 0,
-- EndBlock INTEGER UNSIGNED DEFAULT 0,
-- LocationId INTEGER UNSIGNED REFERENCES Location,
-- RecycleCount INTEGER UNSIGNED DEFAULT 0,
-- InitialWrite DATETIME DEFAULT 0,
-- ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- PRIMARY KEY(MediaId)
-- );
-+DROP TABLE Version;
-
--INSERT INTO Media_backup SELECT
-- MediaId, VolumeName, Slot, PoolId,
-- MediaType, LabelType, 0, FirstWritten, LastWritten,
-- LabelDate, VolJobs, VolFiles, VolBlocks,
-- VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
-- VolCapacityBytes, VolStatus, 1, Recycle,
-- VolRetention, VolUseDuration, MaxVolJobs,
-- MaxVolFiles, MaxVolBytes, InChanger,
-- StorageId, 0, MediaAddressing,
-- VolReadTime, VolWriteTime, EndFile, EndBlock, 0, 0, 0, 0, 0
-- FROM Media;
--
--
--DROP TABLE Media;
--
--CREATE TABLE Media (
-- MediaId INTEGER,
-- VolumeName VARCHAR(128) NOT NULL,
-- Slot INTEGER DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- MediaType VARCHAR(128) NOT NULL,
-- MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0,
-- LabelType TINYINT DEFAULT 0,
-- FirstWritten DATETIME DEFAULT 0,
-- LastWritten DATETIME DEFAULT 0,
-- LabelDate DATETIME DEFAULT 0,
-- VolJobs INTEGER UNSIGNED DEFAULT 0,
-- VolFiles INTEGER UNSIGNED DEFAULT 0,
-- VolBlocks INTEGER UNSIGNED DEFAULT 0,
-- VolMounts INTEGER UNSIGNED DEFAULT 0,
-- VolBytes BIGINT UNSIGNED DEFAULT 0,
-- VolParts INTEGER UNSIGNED DEFAULT 0,
-- VolErrors INTEGER UNSIGNED DEFAULT 0,
-- VolWrites INTEGER UNSIGNED DEFAULT 0,
-- VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
-- VolStatus VARCHAR(20) NOT NULL,
-- Enabled TINYINT DEFAULT 1,
-- Recycle TINYINT DEFAULT 0,
-- VolRetention BIGINT UNSIGNED DEFAULT 0,
-- VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-- MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-- MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-- MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-- InChanger TINYINT DEFAULT 0,
-- StorageId INTEGER UNSIGNED REFERENCES Storage DEFAULT 0,
-- DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0,
-- MediaAddressing TINYINT DEFAULT 0,
-- VolReadTime BIGINT UNSIGNED DEFAULT 0,
-- VolWriteTime BIGINT UNSIGNED DEFAULT 0,
-- EndFile INTEGER UNSIGNED DEFAULT 0,
-- EndBlock INTEGER UNSIGNED DEFAULT 0,
-- LocationId INTEGER UNSIGNED REFERENCES Location DEFAULT 0,
-- RecycleCount INTEGER UNSIGNED DEFAULT 0,
-- InitialWrite DATETIME DEFAULT 0,
-- ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- Comment TEXT,
-- PRIMARY KEY(MediaId)
-+CREATE TABLE Version (
-+ Product CHAR(8),
-+ VersionId INTEGER UNSIGNED NOT NULL
- );
-
--INSERT INTO Media (
-- MediaId, VolumeName, Slot, PoolId,
-- MediaType, MediaTypeId, LabelType, FirstWritten, LastWritten,
-- LabelDate, VolJobs, VolFiles, VolBlocks,
-- VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
-- VolCapacityBytes, VolStatus, Enabled, Recycle,
-- VolRetention, VolUseDuration, MaxVolJobs,
-- MaxVolFiles, MaxVolBytes,
-- InChanger, StorageId, DeviceId, MediaAddressing,
-- VolReadTime, VolWriteTime,
-- EndFile, EndBlock, LocationId, RecycleCount, InitialWrite,
-- ScratchPoolId, RecyclePoolId)
-- SELECT * FROM Media_backup;
-+INSERT INTO Version (Product, VersionId) VALUES ('bacula', 11);
-
--
--DROP TABLE Media_backup;
--CREATE INDEX inx8 ON Media (PoolId);
--
--CREATE TEMPORARY TABLE job_backup
--(
-- JobId INTEGER,
-- Job VARCHAR(128) NOT NULL,
-- Name VARCHAR(128) NOT NULL,
-- Type CHAR NOT NULL,
-- Level CHAR NOT NULL,
-- ClientId INTEGER REFERENCES Client DEFAULT 0,
-- JobStatus CHAR NOT NULL,
-- SchedTime DATETIME NOT NULL,
-- StartTime DATETIME DEFAULT 0,
-- EndTime DATETIME DEFAULT 0,
-- RealEndTime DATETIME DEFAULT 0,
-- JobTDate BIGINT UNSIGNED DEFAULT 0,
-- VolSessionId INTEGER UNSIGNED DEFAULT 0,
-- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-- JobFiles INTEGER UNSIGNED DEFAULT 0,
-- JobBytes BIGINT UNSIGNED DEFAULT 0,
-- JobErrors INTEGER UNSIGNED DEFAULT 0,
-- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-- PurgedFiles TINYINT DEFAULT 0,
-- HasBase TINYINT DEFAULT 0
-- );
--
--INSERT INTO Job_backup SELECT
-- JobId, Job, Name, Type, Level, ClientId, JobStatus,
-- SchedTime, StartTime, EndTime, 0,
-- JobTDate, VolSessionId, VolSessionTime,
-- JobFiles, JobBytes, JobErrors, JobMissingFiles,
-- PoolId, FileSetId, 0, PurgedFiles, HasBase
-- FROM Job;
--
--DROP TABLE Job;
--
--CREATE TABLE Job
--(
-- JobId INTEGER,
-- Job VARCHAR(128) NOT NULL,
-- Name VARCHAR(128) NOT NULL,
-- Type CHAR NOT NULL,
-- Level CHAR NOT NULL,
-- ClientId INTEGER REFERENCES Client DEFAULT 0,
-- JobStatus CHAR NOT NULL,
-- SchedTime DATETIME NOT NULL,
-- StartTime DATETIME DEFAULT 0,
-- EndTime DATETIME DEFAULT 0,
-- RealEndTime DATETIME DEFAULT 0,
-- JobTDate BIGINT UNSIGNED DEFAULT 0,
-- VolSessionId INTEGER UNSIGNED DEFAULT 0,
-- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-- JobFiles INTEGER UNSIGNED DEFAULT 0,
-- JobBytes BIGINT UNSIGNED DEFAULT 0,
-- JobErrors INTEGER UNSIGNED DEFAULT 0,
-- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-- PurgedFiles TINYINT DEFAULT 0,
-- HasBase TINYINT DEFAULT 0,
-- PRIMARY KEY(JobId)
-- );
--CREATE INDEX inx6 ON Job (Name);
--
--INSERT INTO Job (
-- JobId, Job, Name, Type, Level, ClientId, JobStatus,
-- SchedTime, StartTime, EndTime, RealEndTime,
-- JobTDate, VolSessionId, VolSessionTime,
-- JobFiles, JobBytes, JobErrors, JobMissingFiles,
-- PoolId, FileSetId, PriorJobId, PurgedFiles, HasBase)
-- SELECT * FROM Job_backup;
--
--DROP TABLE Job_backup;
--
--CREATE TABLE LocationLog (
-- LocLogId INTEGER,
-- Date DATETIME NOT NULL,
-- Comment TEXT NOT NULL,
-- MediaId INTEGER UNSIGNED REFERENCES Media DEFAULT 0,
-- LocationId INTEGER UNSIGNED REFERENCES LocationId DEFAULT 0,
-- NewVolStatus VARCHAR(20) NOT NULL,
-- NewEnabled TINYINT NOT NULL,
-- PRIMARY KEY(LocLogId)
--);
--
--CREATE TABLE Log (
-- LogId INTEGER,
-- JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
-- Time DATETIME NOT NULL,
-- LogText TEXT NOT NULL,
-- PRIMARY KEY(LogId)
-- );
--CREATE INDEX LogInx1 ON File (JobId);
--
--CREATE TABLE Location (
-- LocationId INTEGER,
-- Location TEXT NOT NULL,
-- Cost INTEGER DEFAULT 0,
-- Enabled TINYINT,
-- PRIMARY KEY(LocationId)
-- );
--
--
--DELETE FROM Version;
--INSERT INTO Version (VersionId) VALUES (10);
--
- COMMIT;
-
- END-OF-DATA
-Index: src/cats/make_postgresql_tables.in
-===================================================================
---- src/cats/make_postgresql_tables.in (révision 5461)
-+++ src/cats/make_postgresql_tables.in (copie de travail)
-@@ -315,6 +315,7 @@
-
- CREATE TABLE version
- (
-+ product char(8),
- versionid integer not null
- );
-
-@@ -364,7 +365,7 @@
- ('p', 'Waiting on higher priority jobs');
-
-
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (Product, VersionId) VALUES ('bacula', 11);
-
- -- Make sure we have appropriate permissions
-
-Index: src/cats/update_sqlite_tables.in
-===================================================================
---- src/cats/update_sqlite_tables.in (révision 5461)
-+++ src/cats/update_sqlite_tables.in (copie de travail)
-@@ -1,10 +1,10 @@
- #!/bin/sh
- #
--# shell script to update SQLite from version 1.38 to 2.0
-+# shell script to update SQLite from version 2.2 to 3
- #
- echo " "
--echo "This script will update a Bacula SQLite database from version 9 to 10"
--echo " which is needed to convert from Bacula version 1.38.x to 2.0.x or higher"
-+echo "This script will update a Bacula SQLite database from version 10 to 11"
-+echo " which is needed to convert from Bacula version 2.2 to 3 or higher"
- echo "Depending on the size of your database,"
- echo "this script may take several minutes to run."
- echo " "
-@@ -17,236 +17,15 @@
- ${bindir}/${sqlite} $* ${db_name}.db <<END-OF-DATA
- BEGIN TRANSACTION;
-
--CREATE TEMPORARY TABLE Media_backup (
-- MediaId INTEGER UNSIGNED AUTOINCREMENT,
-- VolumeName VARCHAR(128) NOT NULL,
-- Slot INTEGER DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- MediaType VARCHAR(128) NOT NULL,
-- MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0,
-- LabelType TINYINT DEFAULT 0,
-- FirstWritten DATETIME DEFAULT 0,
-- LastWritten DATETIME DEFAULT 0,
-- LabelDate DATETIME DEFAULT 0,
-- VolJobs INTEGER UNSIGNED DEFAULT 0,
-- VolFiles INTEGER UNSIGNED DEFAULT 0,
-- VolBlocks INTEGER UNSIGNED DEFAULT 0,
-- VolMounts INTEGER UNSIGNED DEFAULT 0,
-- VolBytes BIGINT UNSIGNED DEFAULT 0,
-- VolParts INTEGER UNSIGNED DEFAULT 0,
-- VolErrors INTEGER UNSIGNED DEFAULT 0,
-- VolWrites INTEGER UNSIGNED DEFAULT 0,
-- VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
-- VolStatus VARCHAR(20) NOT NULL,
-- Enabled TINYINT DEFAULT 1,
-- Recycle TINYINT DEFAULT 0,
-- VolRetention BIGINT UNSIGNED DEFAULT 0,
-- VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-- MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-- MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-- MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-- InChanger TINYINT DEFAULT 0,
-- StorageId INTEGER UNSIGNED REFERENCES Storage,
-- DeviceId INTEGER UNSIGNED REFERENCES Device,
-- MediaAddressing TINYINT DEFAULT 0,
-- VolReadTime BIGINT UNSIGNED DEFAULT 0,
-- VolWriteTime BIGINT UNSIGNED DEFAULT 0,
-- EndFile INTEGER UNSIGNED DEFAULT 0,
-- EndBlock INTEGER UNSIGNED DEFAULT 0,
-- LocationId INTEGER UNSIGNED REFERENCES Location,
-- RecycleCount INTEGER UNSIGNED DEFAULT 0,
-- InitialWrite DATETIME DEFAULT 0,
-- ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- PRIMARY KEY(MediaId)
-- );
-+DROP TABLE Version;
-
--INSERT INTO Media_backup SELECT
-- MediaId, VolumeName, Slot, PoolId,
-- MediaType, LabelType, 0, FirstWritten, LastWritten,
-- LabelDate, VolJobs, VolFiles, VolBlocks,
-- VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
-- VolCapacityBytes, VolStatus, 1, Recycle,
-- VolRetention, VolUseDuration, MaxVolJobs,
-- MaxVolFiles, MaxVolBytes, InChanger,
-- StorageId, 0, MediaAddressing,
-- VolReadTime, VolWriteTime, EndFile, EndBlock, 0, 0, 0, 0, 0
-- FROM Media;
--
--
--DROP TABLE Media;
--
--CREATE TABLE Media (
-- MediaId INTEGER,
-- VolumeName VARCHAR(128) NOT NULL,
-- Slot INTEGER DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- MediaType VARCHAR(128) NOT NULL,
-- MediaTypeId INTEGER UNSIGNED REFERENCES MediaType DEFAULT 0,
-- LabelType TINYINT DEFAULT 0,
-- FirstWritten DATETIME DEFAULT 0,
-- LastWritten DATETIME DEFAULT 0,
-- LabelDate DATETIME DEFAULT 0,
-- VolJobs INTEGER UNSIGNED DEFAULT 0,
-- VolFiles INTEGER UNSIGNED DEFAULT 0,
-- VolBlocks INTEGER UNSIGNED DEFAULT 0,
-- VolMounts INTEGER UNSIGNED DEFAULT 0,
-- VolBytes BIGINT UNSIGNED DEFAULT 0,
-- VolParts INTEGER UNSIGNED DEFAULT 0,
-- VolErrors INTEGER UNSIGNED DEFAULT 0,
-- VolWrites INTEGER UNSIGNED DEFAULT 0,
-- VolCapacityBytes BIGINT UNSIGNED DEFAULT 0,
-- VolStatus VARCHAR(20) NOT NULL,
-- Enabled TINYINT DEFAULT 1,
-- Recycle TINYINT DEFAULT 0,
-- VolRetention BIGINT UNSIGNED DEFAULT 0,
-- VolUseDuration BIGINT UNSIGNED DEFAULT 0,
-- MaxVolJobs INTEGER UNSIGNED DEFAULT 0,
-- MaxVolFiles INTEGER UNSIGNED DEFAULT 0,
-- MaxVolBytes BIGINT UNSIGNED DEFAULT 0,
-- InChanger TINYINT DEFAULT 0,
-- StorageId INTEGER UNSIGNED REFERENCES Storage DEFAULT 0,
-- DeviceId INTEGER UNSIGNED REFERENCES Device DEFAULT 0,
-- MediaAddressing TINYINT DEFAULT 0,
-- VolReadTime BIGINT UNSIGNED DEFAULT 0,
-- VolWriteTime BIGINT UNSIGNED DEFAULT 0,
-- EndFile INTEGER UNSIGNED DEFAULT 0,
-- EndBlock INTEGER UNSIGNED DEFAULT 0,
-- LocationId INTEGER UNSIGNED REFERENCES Location DEFAULT 0,
-- RecycleCount INTEGER UNSIGNED DEFAULT 0,
-- InitialWrite DATETIME DEFAULT 0,
-- ScratchPoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- RecyclePoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- Comment TEXT,
-- PRIMARY KEY(MediaId)
-+CREATE TABLE Version (
-+ Product CHAR(8),
-+ VersionId INTEGER UNSIGNED NOT NULL
- );
-
--INSERT INTO Media (
-- MediaId, VolumeName, Slot, PoolId,
-- MediaType, MediaTypeId, LabelType, FirstWritten, LastWritten,
-- LabelDate, VolJobs, VolFiles, VolBlocks,
-- VolMounts, VolBytes, VolParts, VolErrors, VolWrites,
-- VolCapacityBytes, VolStatus, Enabled, Recycle,
-- VolRetention, VolUseDuration, MaxVolJobs,
-- MaxVolFiles, MaxVolBytes,
-- InChanger, StorageId, DeviceId, MediaAddressing,
-- VolReadTime, VolWriteTime,
-- EndFile, EndBlock, LocationId, RecycleCount, InitialWrite,
-- ScratchPoolId, RecyclePoolId)
-- SELECT * FROM Media_backup;
-+INSERT INTO Version (Product, VersionId) VALUES ('bacula', 11);
-
--
--DROP TABLE Media_backup;
--CREATE INDEX inx8 ON Media (PoolId);
--
--CREATE TEMPORARY TABLE job_backup
--(
-- JobId INTEGER,
-- Job VARCHAR(128) NOT NULL,
-- Name VARCHAR(128) NOT NULL,
-- Type CHAR NOT NULL,
-- Level CHAR NOT NULL,
-- ClientId INTEGER REFERENCES Client DEFAULT 0,
-- JobStatus CHAR NOT NULL,
-- SchedTime DATETIME NOT NULL,
-- StartTime DATETIME DEFAULT 0,
-- EndTime DATETIME DEFAULT 0,
-- RealEndTime DATETIME DEFAULT 0,
-- JobTDate BIGINT UNSIGNED DEFAULT 0,
-- VolSessionId INTEGER UNSIGNED DEFAULT 0,
-- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-- JobFiles INTEGER UNSIGNED DEFAULT 0,
-- JobBytes BIGINT UNSIGNED DEFAULT 0,
-- JobErrors INTEGER UNSIGNED DEFAULT 0,
-- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-- PurgedFiles TINYINT DEFAULT 0,
-- HasBase TINYINT DEFAULT 0
-- );
--
--INSERT INTO Job_backup SELECT
-- JobId, Job, Name, Type, Level, ClientId, JobStatus,
-- SchedTime, StartTime, EndTime, 0,
-- JobTDate, VolSessionId, VolSessionTime,
-- JobFiles, JobBytes, JobErrors, JobMissingFiles,
-- PoolId, FileSetId, 0, PurgedFiles, HasBase
-- FROM Job;
--
--DROP TABLE Job;
--
--CREATE TABLE Job
--(
-- JobId INTEGER,
-- Job VARCHAR(128) NOT NULL,
-- Name VARCHAR(128) NOT NULL,
-- Type CHAR NOT NULL,
-- Level CHAR NOT NULL,
-- ClientId INTEGER REFERENCES Client DEFAULT 0,
-- JobStatus CHAR NOT NULL,
-- SchedTime DATETIME NOT NULL,
-- StartTime DATETIME DEFAULT 0,
-- EndTime DATETIME DEFAULT 0,
-- RealEndTime DATETIME DEFAULT 0,
-- JobTDate BIGINT UNSIGNED DEFAULT 0,
-- VolSessionId INTEGER UNSIGNED DEFAULT 0,
-- VolSessionTime INTEGER UNSIGNED DEFAULT 0,
-- JobFiles INTEGER UNSIGNED DEFAULT 0,
-- JobBytes BIGINT UNSIGNED DEFAULT 0,
-- JobErrors INTEGER UNSIGNED DEFAULT 0,
-- JobMissingFiles INTEGER UNSIGNED DEFAULT 0,
-- PoolId INTEGER UNSIGNED REFERENCES Pool DEFAULT 0,
-- FileSetId INTEGER UNSIGNED REFERENCES FileSet DEFAULT 0,
-- PriorJobId INTEGER UNSIGNED REFERENCES Job DEFAULT 0,
-- PurgedFiles TINYINT DEFAULT 0,
-- HasBase TINYINT DEFAULT 0,
-- PRIMARY KEY(JobId)
-- );
--CREATE INDEX inx6 ON Job (Name);
--
--INSERT INTO Job (
-- JobId, Job, Name, Type, Level, ClientId, JobStatus,
-- SchedTime, StartTime, EndTime, RealEndTime,
-- JobTDate, VolSessionId, VolSessionTime,
-- JobFiles, JobBytes, JobErrors, JobMissingFiles,
-- PoolId, FileSetId, PriorJobId, PurgedFiles, HasBase)
-- SELECT * FROM Job_backup;
--
--DROP TABLE Job_backup;
--
--CREATE TABLE LocationLog (
-- LocLogId INTEGER,
-- Date DATETIME NOT NULL,
-- Comment TEXT NOT NULL,
-- MediaId INTEGER UNSIGNED REFERENCES Media DEFAULT 0,
-- LocationId INTEGER UNSIGNED REFERENCES LocationId DEFAULT 0,
-- NewVolStatus VARCHAR(20) NOT NULL,
-- NewEnabled TINYINT NOT NULL,
-- PRIMARY KEY(LocLogId)
--);
--
--CREATE TABLE Log (
-- LogId INTEGER,
-- JobId INTEGER UNSIGNED REFERENCES Job NOT NULL,
-- Time DATETIME NOT NULL,
-- LogText TEXT NOT NULL,
-- PRIMARY KEY(LogId)
-- );
--CREATE INDEX LogInx1 ON File (JobId);
--
--CREATE TABLE Location (
-- LocationId INTEGER,
-- Location TEXT NOT NULL,
-- Cost INTEGER DEFAULT 0,
-- Enabled TINYINT,
-- PRIMARY KEY(LocationId)
-- );
--
--
--DELETE FROM Version;
--INSERT INTO Version (VersionId) VALUES (10);
--
- COMMIT;
-
- END-OF-DATA
-Index: src/cats/update_mysql_tables.in
-===================================================================
---- src/cats/update_mysql_tables.in (révision 5461)
-+++ src/cats/update_mysql_tables.in (copie de travail)
-@@ -1,10 +1,10 @@
- #!/bin/sh
- #
--# Shell script to update MySQL tables from version 1.38 to 2.0
-+# Shell script to update MySQL tables from version 2.2 to 3
- #
- echo " "
--echo "This script will update a Bacula MySQL database from version 9 to 10"
--echo " which is needed to convert from Bacula version 1.38.x to 2.0.x or higher"
-+echo "This script will update a Bacula MySQL database from version 10 to 11"
-+echo " which is needed to convert from Bacula version 2.2 to 3 or higher"
- echo "Depending on the size of your database,"
- echo "this script may take several minutes to run."
- echo " "
-@@ -14,59 +14,12 @@
- if $bindir/mysql $* -f <<END-OF-DATA
- USE ${db_name};
-
--DROP TABLE IF EXISTS MAC;
--DROP TABLE IF EXISTS Log;
--DROP TABLE IF EXISTS Location;
--DROP TABLE IF EXISTS LocationLog;
-+ALTER TABLE Version ADD COLUMN Product char(8) default '';
-
--CREATE TABLE Log (
-- LogId INTEGER UNSIGNED AUTO_INCREMENT,
-- JobId INTEGER UNSIGNED DEFAULT 0 REFERENCES Job,
-- Time DATETIME DEFAULT 0,
-- LogText BLOB NOT NULL,
-- PRIMARY KEY(LogId),
-- INDEX (JobId)
-- );
-
--CREATE TABLE Location (
-- LocationId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-- Location TINYBLOB NOT NULL,
-- Cost INTEGER DEFAULT 0,
-- Enabled TINYINT,
-- PRIMARY KEY(LocationId)
-- );
-
--CREATE TABLE LocationLog (
-- LocLogId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
-- Date DATETIME DEFAULT 0,
-- Comment BLOB,
-- MediaId INTEGER UNSIGNED DEFAULT 0 REFERENCES Media,
-- LocationId INTEGER UNSIGNED DEFAULT 0 REFERENCES Location,
-- NewVolStatus ENUM('Full', 'Archive', 'Append', 'Recycle', 'Purged',
-- 'Read-Only', 'Disabled', 'Error', 'Busy', 'Used', 'Cleaning') NOT NULL,
-- NewEnabled TINYINT,
-- PRIMARY KEY(LocLogId)
--);
--
--ALTER TABLE Media ADD COLUMN MediaTypeId INTEGER UNSIGNED DEFAULT 0 REFERENCES MediaType;
--ALTER TABLE Media ADD COLUMN DeviceId INTEGER UNSIGNED DEFAULT 0 REFERENCES Device;
--ALTER TABLE Media ADD COLUMN LocationId INTEGER UNSIGNED DEFAULT 0 REFERENCES Location;
--ALTER TABLE Media ADD COLUMN RecycleCount INTEGER UNSIGNED DEFAULT 0;
--ALTER TABLE Media ADD COLUMN InitialWrite DATETIME DEFAULT 0;
--ALTER TABLE Media ADD COLUMN ScratchPoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool;
--ALTER TABLE Media ADD COLUMN RecyclePoolId INTEGER UNSIGNED DEFAULT 0 REFERENCES Pool;
--ALTER TABLE Media ADD COLUMN Enabled TINYINT DEFAULT 1;
--ALTER TABLE Media ADD COLUMN Comment BLOB;
--
--ALTER TABLE JobMedia DROP COLUMN Stripe;
--
--ALTER TABLE Job ADD COLUMN PriorJobId INTEGER UNSIGNED DEFAULT 0 REFERENCES Job;
--ALTER TABLE Job ADD COLUMN RealEndTime DATETIME DEFAULT 0;
--
--
--
- DELETE FROM Version;
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (Product, VersionId) VALUES ('bacula', 11);
-
- END-OF-DATA
- then
-Index: src/cats/make_sqlite_tables.in
-===================================================================
---- src/cats/make_sqlite_tables.in (révision 5461)
-+++ src/cats/make_sqlite_tables.in (copie de travail)
-@@ -283,6 +283,7 @@
- INSERT INTO NextId (id, TableName) VALUES (1, "Job");
-
- CREATE TABLE Version (
-+ Product CHAR(8),
- VersionId INTEGER UNSIGNED NOT NULL
- );
-
-@@ -350,7 +351,7 @@
-
-
- -- Initialize Version
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (Product, VersionId) VALUES ('bacula', 11);
-
-
- PRAGMA default_synchronous = OFF;
-Index: src/cats/make_mysql_tables.in
-===================================================================
---- src/cats/make_mysql_tables.in (révision 5461)
-+++ src/cats/make_mysql_tables.in (copie de travail)
-@@ -328,11 +328,12 @@
- ('p', 'Waiting on higher priority jobs');
-
- CREATE TABLE Version (
-- VersionId INTEGER UNSIGNED NOT NULL
-+ Product CHAR(8),
-+ VersionId INTEGER UNSIGNED NOT NULL,
- );
-
- -- Initialize Version
--INSERT INTO Version (VersionId) VALUES (10);
-+INSERT INTO Version (Product, VersionId) VALUES ('bacula', 11);
-
- END-OF-DATA
- then
+++ /dev/null
-From: Eric Bollengier <eric at homelinux dot org>
-
-This patch add a column to the Version table of the catalog.
-For example, bweb and brestore are using private tables, and
-it is useful to store the schema version in the same table.
-
-Product | Version
----------+---------
-bacula | 10
-bweb | 2
-brestore | 3
-
-instead of
-
-Version
--------
- 10
+++ /dev/null
-Index: src/dird/autoprune.c
-===================================================================
---- src/dird/autoprune.c (révision 7380)
-+++ src/dird/autoprune.c (copie de travail)
-@@ -96,7 +96,7 @@
- POOL_MEM query(PM_MESSAGE);
- UAContext *ua;
- bool ok = false;
-- char ed1[50], ed2[100], ed3[50];
-+ char ed1[50], ed2[100];
- POOL_DBR spr;
-
- Dmsg1(050, "Prune volumes PoolId=%d\n", jcr->jr.PoolId);
-@@ -141,15 +141,9 @@
- "(PoolId=%s OR RecyclePoolId IN (%s)) AND MediaType='%s' %s"
- "ORDER BY LastWritten ASC,MediaId";
-
-- if (InChanger) {
-- char changer[100];
-- /* Ensure it is in this autochanger */
-- bsnprintf(changer, sizeof(changer), "AND InChanger=1 AND StorageId=%s ",
-- edit_int64(mr->StorageId, ed3));
-- Mmsg(query, select, ed1, ed2, mr->MediaType, changer);
-- } else {
-- Mmsg(query, select, ed1, ed2, mr->MediaType, "");
-- }
-+ POOL_MEM changer(PM_MESSAGE);
-+ db_select_autochanger(ua->jcr, ua->db, InChanger, mr->StorageId, changer);
-+ Mmsg(query, select, ed1, ed2, mr->MediaType, changer.c_str());
-
- Dmsg1(050, "query=%s\n", query.c_str());
- if (!db_get_query_dbids(ua->jcr, ua->db, query, ids)) {
-Index: src/dird/dird.c
-===================================================================
---- src/dird/dird.c (révision 7380)
-+++ src/dird/dird.c (copie de travail)
-@@ -933,6 +933,7 @@
- }
- bstrncpy(sr.Name, store->name(), sizeof(sr.Name));
- sr.AutoChanger = store->autochanger;
-+ sr.AutoChangerId = 0; /* don't know if it's in big autochanger */
- db_create_storage_record(NULL, db, &sr);
- store->StorageId = sr.StorageId; /* set storage Id */
- if (!sr.created) { /* if not created, update it */
-@@ -974,7 +975,21 @@
- }
- }
- }
--
-+ /* Update Autochanger properties */
-+ db_reset_storage_autochangerid(NULL, db); /* reset AutoChangerId for each storage */
-+ foreach_res(store, R_STORAGE) {
-+ if (store->storage_member) { /* This storage owns other storages */
-+ STORE *elt;
-+ foreach_alist(elt, store->storage_member) {
-+ STORAGE_DBR sr;
-+ bstrncpy(sr.Name, elt->name(), sizeof(sr.Name));
-+ sr.StorageId = elt->StorageId;
-+ sr.AutoChanger = elt->autochanger;
-+ sr.AutoChangerId = store->StorageId;
-+ db_update_storage_record(NULL, db, &sr);
-+ }
-+ }
-+ }
- /* Loop over all counters, defining them in each database */
- /* Set default value in all counters */
- COUNTER *counter;
-Index: src/dird/dird_conf.c
-===================================================================
---- src/dird/dird_conf.c (révision 7380)
-+++ src/dird/dird_conf.c (copie de travail)
-@@ -218,6 +218,7 @@
- {"mediatype", store_strname, ITEM(res_store.media_type), 0, ITEM_REQUIRED, 0},
- {"autochanger", store_bool, ITEM(res_store.autochanger), 0, ITEM_DEFAULT, 0},
- {"enabled", store_bool, ITEM(res_store.enabled), 0, ITEM_DEFAULT, true},
-+ {"contains", store_alist_res,ITEM(res_store.storage_member), R_STORAGE, 0, 0},
- {"heartbeatinterval", store_time, ITEM(res_store.heartbeat_interval), 0, ITEM_DEFAULT, 0},
- {"maximumconcurrentjobs", store_pint32, ITEM(res_store.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1},
- {"sddport", store_pint32, ITEM(res_store.SDDport), 0, 0, 0}, /* deprecated */
-@@ -1161,6 +1162,9 @@
- if (res->res_store.device) {
- delete res->res_store.device;
- }
-+ if (res->res_store.storage_member) {
-+ delete res->res_store.storage_member;
-+ }
- if (res->res_store.tls_ctx) {
- free_tls_context(res->res_store.tls_ctx);
- }
-@@ -1395,6 +1399,7 @@
- }
- /* we must explicitly copy the device alist pointer */
- res->res_store.device = res_all.res_store.device;
-+ res->res_store.storage_member = res_all.res_store.storage_member;
- break;
- case R_JOB:
- case R_JOBDEFS:
-Index: src/dird/dird_conf.h
-===================================================================
---- src/dird/dird_conf.h (révision 7380)
-+++ src/dird/dird_conf.h (copie de travail)
-@@ -290,6 +290,7 @@
- char *password;
- char *media_type;
- alist *device; /* Alternate devices for this Storage */
-+ alist *storage_member;
- uint32_t MaxConcurrentJobs; /* Maximume concurrent jobs */
- uint32_t NumConcurrentJobs; /* number of concurrent jobs running */
- uint32_t NumConcurrentReadJobs; /* number of jobs reading */
-Index: src/cats/sql_update.c
-===================================================================
---- src/cats/sql_update.c (révision 7380)
-+++ src/cats/sql_update.c (copie de travail)
-@@ -288,14 +288,27 @@
- }
-
- bool
-+db_reset_storage_autochangerid(JCR *jcr, B_DB *mdb)
-+{
-+ int stat;
-+ Dmsg0(50, "reset storage autochangerid\n");
-+ db_lock(mdb);
-+ Mmsg(mdb->cmd, "UPDATE Storage SET AutoChangerId=0 "); /* Change to Autochanger */
-+ stat = UPDATE_DB(jcr, mdb, mdb->cmd);
-+ db_unlock(mdb);
-+ return stat;
-+}
-+
-+bool
- db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
- {
- int stat;
-- char ed1[50];
-+ char ed1[50], ed2[50];
-
- db_lock(mdb);
-- Mmsg(mdb->cmd, "UPDATE Storage SET AutoChanger=%d WHERE StorageId=%s",
-- sr->AutoChanger, edit_int64(sr->StorageId, ed1));
-+ /* TODO: if autochangerid is set, update AutoChanger table */
-+ Mmsg(mdb->cmd, "UPDATE Storage SET AutoChanger=%d, AutoChangerId=%s WHERE StorageId=%s",
-+ sr->AutoChanger, edit_int64(sr->AutoChangerId, ed2), edit_int64(sr->StorageId, ed1));
-
- stat = UPDATE_DB(jcr, mdb, mdb->cmd);
- db_unlock(mdb);
-Index: src/cats/update_postgresql_tables.in
-===================================================================
---- src/cats/update_postgresql_tables.in (révision 7380)
-+++ src/cats/update_postgresql_tables.in (copie de travail)
-@@ -14,6 +14,9 @@
- -- Create a table like Job for long term statistics
- CREATE TABLE jobstat (LIKE job);
-
-+ALTER TABLE Storage ADD COLUMN AutoChangerId integer;
-+ALTER TABLE Storage ALTER COLUMN AutoChangerId SET DEFAULT 0;
-+
- UPDATE version SET versionid=11;
-
- vacuum analyse;
-Index: src/cats/make_sqlite3_tables.in
-===================================================================
---- src/cats/make_sqlite3_tables.in (révision 7380)
-+++ src/cats/make_sqlite3_tables.in (copie de travail)
-@@ -218,6 +218,7 @@
- StorageId INTEGER,
- Name VARCHAR(128) NOT NULL,
- AutoChanger TINYINT DEFAULT 0,
-+ AutoChangerId INTEGER DEFAULT 0,
- PRIMARY KEY(StorageId)
- );
-
-Index: src/cats/cats.h
-===================================================================
---- src/cats/cats.h (révision 7380)
-+++ src/cats/cats.h (copie de travail)
-@@ -939,7 +939,7 @@
- DBId_t StorageId;
- char Name[MAX_NAME_LENGTH]; /* Device name */
- int AutoChanger; /* Set if autochanger */
--
-+ int AutoChangerId; /* Group devices in autochanger */
- /* Not in database */
- bool created; /* set if created by db_create ... */
- };
-Index: src/cats/make_postgresql_tables.in
-===================================================================
---- src/cats/make_postgresql_tables.in (révision 7380)
-+++ src/cats/make_postgresql_tables.in (copie de travail)
-@@ -185,6 +185,7 @@
- StorageId SERIAL,
- Name TEXT NOT NULL,
- AutoChanger INTEGER DEFAULT 0,
-+ AutoChangerId INTEGER DEFAULT 0,
- PRIMARY KEY(StorageId)
- );
-
-Index: src/cats/update_mysql_tables.in
-===================================================================
---- src/cats/update_mysql_tables.in (révision 7380)
-+++ src/cats/update_mysql_tables.in (copie de travail)
-@@ -15,6 +15,9 @@
- -- Create a table like Job for long term statistics
- CREATE TABLE JobStat (LIKE Job);
-
-+ALTER TABLE Storage ADD COLUMN AutoChangerId integer;
-+ALTER TABLE Storage ALTER COLUMN AutoChangerId SET DEFAULT 0;
-+
- DELETE FROM Version;
- INSERT INTO Version (VersionId) VALUES (11);
-
-Index: src/cats/protos.h
-===================================================================
---- src/cats/protos.h (révision 7380)
-+++ src/cats/protos.h (copie de travail)
-@@ -123,10 +123,12 @@
- void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-
- /* sql_update.c */
-+void db_select_autochanger(JCR *jcr, B_DB *mdb, bool InChanger, DBId_t StorageId, POOL_MEM &result);
- bool db_update_job_start_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
- int db_update_job_end_record(JCR *jcr, B_DB *db, JOB_DBR *jr, bool stats_enabled);
- int db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
- int db_update_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pr);
-+bool db_reset_storage_autochangerid(JCR *jcr, B_DB *db);
- bool db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr);
- int db_update_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *mr);
- int db_update_media_defaults(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr);
-Index: src/cats/sql_find.c
-===================================================================
---- src/cats/sql_find.c (révision 7380)
-+++ src/cats/sql_find.c (copie de travail)
-@@ -305,6 +305,26 @@
- return true;
- }
-
-+void db_select_autochanger(JCR *jcr, B_DB *mdb, bool InChanger, DBId_t StorageId, POOL_MEM &result)
-+{
-+ char ed1[50];
-+
-+ if (InChanger) {
-+ edit_int64(StorageId, ed1);
-+ Mmsg(result,
-+ "AND InChanger=1 "
-+ "AND ( StorageId IN "
-+ "( SELECT StorageId "
-+ "FROM Storage "
-+ "WHERE AutoChangerId = %s "
-+ ") "
-+ "OR StorageId=%s)",
-+ ed1, ed1);
-+ } else {
-+ Mmsg(result, "");
-+ }
-+}
-+
- /*
- * Find Available Media (Volume) for Pool
- *
-@@ -338,12 +358,9 @@
- edit_int64(mr->PoolId, ed1), mr->MediaType);
- item = 1;
- } else {
-- POOL_MEM changer(PM_FNAME);
-- /* Find next available volume */
-- if (InChanger) {
-- Mmsg(changer, "AND InChanger=1 AND StorageId=%s",
-- edit_int64(mr->StorageId, ed1));
-- }
-+ POOL_MEM changer(PM_MESSAGE);
-+ db_select_autochanger(jcr, mdb, InChanger, mr->StorageId, changer);
-+
- if (strcmp(mr->VolStatus, "Recycle") == 0 ||
- strcmp(mr->VolStatus, "Purged") == 0) {
- order = "AND Recycle=1 ORDER BY LastWritten ASC,MediaId"; /* take oldest that can be recycled */
-Index: src/cats/make_sqlite_tables.in
-===================================================================
---- src/cats/make_sqlite_tables.in (révision 7380)
-+++ src/cats/make_sqlite_tables.in (copie de travail)
-@@ -218,6 +218,7 @@
- StorageId INTEGER,
- Name VARCHAR(128) NOT NULL,
- AutoChanger TINYINT DEFAULT 0,
-+ AutoChangerId INTEGER DEFAULT 0,
- PRIMARY KEY(StorageId)
- );
-
-Index: src/cats/sql_create.c
-===================================================================
---- src/cats/sql_create.c (révision 7380)
-+++ src/cats/sql_create.c (copie de travail)
-@@ -279,7 +279,7 @@
- bool ok;
-
- db_lock(mdb);
-- Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger FROM Storage WHERE Name='%s'", sr->Name);
-+ Mmsg(mdb->cmd, "SELECT StorageId,AutoChanger,AutoChangerId FROM Storage WHERE Name='%s'", sr->Name);
-
- sr->StorageId = 0;
- sr->created = false;
-@@ -300,6 +300,7 @@
- }
- sr->StorageId = str_to_int64(row[0]);
- sr->AutoChanger = atoi(row[1]); /* bool */
-+ sr->AutoChangerId = str_to_int64(row[2]);
- sql_free_result(mdb);
- db_unlock(mdb);
- return true;
-@@ -308,8 +309,8 @@
- }
-
- /* Must create it */
-- Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger)"
-- " VALUES ('%s',%d)", sr->Name, sr->AutoChanger);
-+ Mmsg(mdb->cmd, "INSERT INTO Storage (Name,AutoChanger,AutoChangerId)"
-+ " VALUES ('%s',%d,%d)", sr->Name, sr->AutoChanger, sr->AutoChangerId);
-
- if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
- Mmsg2(&mdb->errmsg, _("Create DB Storage record %s failed. ERR=%s\n"),
-Index: src/cats/make_mysql_tables.in
-===================================================================
---- src/cats/make_mysql_tables.in (révision 7380)
-+++ src/cats/make_mysql_tables.in (copie de travail)
-@@ -64,6 +64,7 @@
- StorageId INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
- Name TINYBLOB NOT NULL,
- AutoChanger TINYINT DEFAULT 0,
-+ AutoChangerId INTEGER DEFAULT 0,
- PRIMARY KEY(StorageId)
- );
-
-Index: src/stored/stored_conf.h
-===================================================================
---- src/stored/stored_conf.h (révision 7380)
-+++ src/stored/stored_conf.h (copie de travail)
-@@ -99,7 +99,7 @@
- char *tls_keyfile; /* TLS Server Key File */
- char *tls_dhfile; /* TLS Diffie-Hellman Parameters */
- alist *tls_allowed_cns; /* TLS Allowed Clients */
--
-+ alist *storage_member; /* Storage in the same Autochanger */
- TLS_CONTEXT *tls_ctx; /* Shared TLS Context */
- };
- typedef class s_res_store STORES;
+++ /dev/null
-From: Eric Bollengier <eric AT eb.homelinux.org>
-
-This patch allow you to use Batch insert mode with all database.
-It have tested this with postgresql 8.1 and mysql 4.1 and sqlite.
-You have to add to src/baconfig.h
-#define HAVE_BATCH_FILE_INSERT 1
-
-and you MUST change some indexes.
-
-mysql)
-
-ALTER TABLE Filename DROP INDEX Name;
-ALTER TABLE Filename ADD UNIQUE (Name(255));
-
-ALTER TABLE Path DROP INDEX Path;
-ALTER TABLE Path ADD UNIQUE (Path(255));
-
-postgresql)
-
-DROP INDEX filename_name_idx;
-CREATE UNIQUE INDEX filename_name_idx on filename (name);
-
-DROP INDEX path_name_idx;
-CREATE UNIQUE INDEX path_name_idx on path (path);
-
-sqlite)
-
-drop index inx2;
-drop index inx1;
-CREATE UNIQUE INDEX path_name_idx on path (path);
-CREATE UNIQUE INDEX filename_name_idx on filename (name);
-
-$Log$
-Revision 1.2 2007/01/01 16:52:05 ricozz
-ebl add #define in readme
-ebl works with 2.0.0
-
-Revision 1.1 2006/12/20 18:47:42 ricozz
-ebl works with 1.39.30
-
+++ /dev/null
-/*
- * Test program for testing regular expressions.
- *
- * Kern Sibbald, MMVI
- *
- */
-/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2006-2006 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.
- This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation and included
- in the file LICENSE.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Bacula® is a registered trademark of John Walker.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-*/
-
-/*
- * If you define BACULA_REGEX, bregex will be built with the
- * Bacula bregex library, which is the same code that we
- * use on Win32, thus using Linux, you can test your Win32
- * expressions. Otherwise, this program will link with the
- * system library routines.
- */
-//#define BACULA_REGEX
-
-#include "bacula.h"
-#include <stdio.h>
-#include "lib/breg.h"
-
-
-static void usage()
-{
- fprintf(stderr,
-"\n"
-"Usage: bregex [-d debug_level] -f <data-file> -e /test/test2/\n"
-" -f specify file of data to be matched\n"
-" -e specify expression\n"
-" -? print this message.\n"
-"\n");
-
- exit(1);
-}
-
-
-int main(int argc, char *const *argv)
-{
- regex_t preg;
- char prbuf[500];
- char *fname = NULL;
- char *expr = NULL;
- int rc, ch;
- char data[1000];
- char pat[500];
- FILE *fd;
- bool match_only = true;
- int lineno;
- bool no_linenos = false;
-
-
- setlocale(LC_ALL, "");
- bindtextdomain("bacula", LOCALEDIR);
- textdomain("bacula");
-
- while ((ch = getopt(argc, argv, "d:f:e:")) != -1) {
- switch (ch) {
- case 'd': /* set debug level */
- debug_level = atoi(optarg);
- if (debug_level <= 0) {
- debug_level = 1;
- }
- break;
-
- case 'f': /* data */
- fname = optarg;
- break;
-
- case 'e':
- expr = optarg;
- break;
-
- case '?':
- default:
- usage();
-
- }
- }
- argc -= optind;
- argv += optind;
-
- if (!fname) {
- printf("A data file must be specified.\n");
- usage();
- }
-
- if (!expr) {
- printf("An expression must be specified.\n");
- usage();
- }
-
- OSDependentInit();
-
- BREGEXP *reg;
-
- reg = new_bregexp(expr);
-
- if (!reg) {
- printf("Can't use %s as 'sed' expression\n", expr);
- exit (1);
- }
-
- fd = fopen(fname, "r");
- if (!fd) {
- printf(_("Could not open data file: %s\n"), fname);
- exit(1);
- }
-
- while (fgets(data, sizeof(data)-1, fd)) {
- strip_trailing_newline(data);
- reg->replace(data);
- printf("%s\n", reg->result);
- }
- fclose(fd);
- free_bregexp(reg);
- exit(0);
-}
-/*
- TODO:
- - ajout /g
-
- - tests
- * test avec /i (visiblement il ne marche pas sur bregexp.c)
- * test avec un sed et faire un diff
- * test avec une boucle pour voir les fuites
- * tester les cas possibles pour la compilation d'une expression
- - manque le depart, le milieu, la fin, utilise des groupes sans
- reference...
-
-*/
+++ /dev/null
-Index: src/stored/mount.c
-===================================================================
---- src/stored/mount.c (revision 6978)
-+++ src/stored/mount.c (working copy)
-@@ -290,7 +290,9 @@
- if (!is_eod_valid()) {
- goto mount_next_vol;
- }
--
-+ if (!dev->VolCatInfo.VolFirstWritten) {
-+ dev->VolCatInfo.VolFirstWritten = time(NULL);
-+ }
- dev->VolCatInfo.VolCatMounts++; /* Update mounts */
- Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
- if (!dir_update_volume_info(dcr, false, false)) {
+++ /dev/null
-Index: src/dird/backup.c
-===================================================================
---- src/dird/backup.c (révision 7736)
-+++ src/dird/backup.c (copie de travail)
-@@ -326,24 +326,26 @@
- }
- return false;
-
--/* Come here only after starting SD thread */
-+/* Come here only after starting SD thread
-+ * and we don't expect any EndJob message because the
-+ * the client don't have recieve the "backup" command.
-+ */
- bail_out:
- set_jcr_job_status(jcr, JS_ErrorTerminated);
-- Dmsg1(400, "wait for sd. use=%d\n", jcr->use_count());
-- /* Cancel SD */
-- wait_for_job_termination(jcr, FDConnectTimeout);
-- Dmsg1(400, "after wait for sd. use=%d\n", jcr->use_count());
-+ Dmsg1(400, "wait for sd and fd. use=%d\n", jcr->use_count());
-+ /* Get status from SD and FD */
-+ wait_for_job_termination(jcr, false /* don't expect EndJob message*/);
-+ Dmsg1(400, "after wait for sd and fd. use=%d\n", jcr->use_count());
- return false;
- }
-
--
- /*
- * Here we wait for the File daemon to signal termination,
- * then we wait for the Storage daemon. When both
- * are done, we return the job status.
- * Also used by restore.c
- */
--int wait_for_job_termination(JCR *jcr, int timeout)
-+int wait_for_job_termination(JCR *jcr, bool expect_EndJob)
- {
- int32_t n = 0;
- BSOCK *fd = jcr->file_bsock;
-@@ -353,40 +355,49 @@
- uint64_t JobBytes = 0;
- int VSS = 0;
- int Encrypt = 0;
-- btimer_t *tid=NULL;
--
- set_jcr_job_status(jcr, JS_Running);
-
- if (fd) {
-- if (timeout) {
-- tid = start_bsock_timer(fd, timeout); /* TODO: New timeout directive??? */
-- }
-- /* Wait for Client to terminate */
-- while ((n = bget_dirmsg(fd)) >= 0) {
-- if (!fd_ok &&
-- (sscanf(fd->msg, EndJob, &jcr->FDJobStatus, &JobFiles,
-- &ReadBytes, &JobBytes, &Errors, &VSS, &Encrypt) == 7 ||
-- sscanf(fd->msg, OldEndJob, &jcr->FDJobStatus, &JobFiles,
-- &ReadBytes, &JobBytes, &Errors) == 5)) {
-- fd_ok = true;
-- set_jcr_job_status(jcr, jcr->FDJobStatus);
-- Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
-- } else {
-- Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
-- fd->msg);
-+ /* Wait for Client to terminate
-+ * In some conditions, the client isn't able to send
-+ * any messages and we should not wait for ages
-+ */
-+ int OK=true;
-+ int ret;
-+ while (OK && expect_EndJob) {
-+
-+ /* Even if the job is canceled, we let a chance to FD to
-+ * send EndJob message
-+ */
-+ if (job_canceled(jcr)) {
-+ OK=false;
- }
-- if (job_canceled(jcr)) {
-- break;
-+
-+ /* wait for data few minutes */
-+ ret = fd->wait_data_intr(3*60, 0);
-+ if (ret == 1) { /* get data */
-+ n = bget_dirmsg(fd);
-+ if (n >= 0 &&
-+ (sscanf(fd->msg, EndJob, &jcr->FDJobStatus, &JobFiles,
-+ &ReadBytes, &JobBytes, &Errors, &VSS, &Encrypt) == 7 ||
-+ sscanf(fd->msg, OldEndJob, &jcr->FDJobStatus, &JobFiles,
-+ &ReadBytes, &JobBytes, &Errors) == 5)) {
-+ fd_ok = true;
-+ set_jcr_job_status(jcr, jcr->FDJobStatus);
-+ OK=false; /* end of loop */
-+ } else {
-+ Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
-+ fd->msg);
-+ }
-+ } /* else get timeout or network error */
-+
-+ if (is_bnet_error(fd)) {
-+ Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"),
-+ job_type_to_str(jcr->get_JobType()), fd->bstrerror());
-+ OK=false;
- }
- }
-- if (tid) {
-- stop_bsock_timer(tid);
-- }
-
-- if (is_bnet_error(fd)) {
-- Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"),
-- job_type_to_str(jcr->get_JobType()), fd->bstrerror());
-- }
- fd->signal(BNET_TERMINATE); /* tell Client we are terminating */
- }
-
-Index: src/dird/protos.h
-===================================================================
---- src/dird/protos.h (révision 7736)
-+++ src/dird/protos.h (copie de travail)
-@@ -52,7 +52,7 @@
- extern bool find_recycled_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr);
-
- /* backup.c */
--extern int wait_for_job_termination(JCR *jcr, int timeout=0);
-+extern int wait_for_job_termination(JCR *jcr, bool expect_EndJob=true);
- extern bool do_backup_init(JCR *jcr);
- extern bool do_backup(JCR *jcr);
- extern void backup_cleanup(JCR *jcr, int TermCode);
+++ /dev/null
-This patch fixes all orphan jobs from catalog (Running/Created) during
-startup.
-
-This avoid phantom jobs with bweb or bat.
-
- cd <bacula-source>
- patch -p0 < cleanup_CR_catalog_at_start.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-Index: src/dird/dird.c
-===================================================================
---- src/dird/dird.c (revision 7176)
-+++ src/dird/dird.c (working copy)
-@@ -40,6 +40,7 @@
- /* Forward referenced subroutines */
- void terminate_dird(int sig);
- static bool check_resources();
-+static void cleanup_catalog();
- static bool check_catalog();
- static void dir_sql_query(JCR *jcr, const char *cmd);
-
-@@ -286,6 +287,8 @@
- set_thread_concurrency(director->MaxConcurrentJobs * 2 +
- 4 /* UA */ + 4 /* sched+watchdog+jobsvr+misc */);
-
-+ cleanup_catalog(); /* cleanup old running jobs */
-+
- Dmsg0(200, "Start UA server\n");
- start_UA_server(director->DIRaddrs);
-
-@@ -881,6 +884,38 @@
- return OK;
- }
-
-+/* Cleanup old catalog records during starting */
-+static void cleanup_catalog()
-+{
-+ CAT *catalog;
-+ foreach_res(catalog, R_CATALOG) {
-+ B_DB *db;
-+ /*
-+ * Make sure we can open catalog, otherwise print a warning
-+ * message because the server is probably not running.
-+ */
-+ db = db_init(NULL, catalog->db_driver, catalog->db_name, catalog->db_user,
-+ catalog->db_password, catalog->db_address,
-+ catalog->db_port, catalog->db_socket,
-+ catalog->mult_db_connections);
-+ if (!db || !db_open_database(NULL, db)) {
-+ Pmsg2(000, _("Could not open Catalog \"%s\", database \"%s\".\n"),
-+ catalog->name(), catalog->db_name);
-+ Jmsg(NULL, M_FATAL, 0, _("Could not open Catalog \"%s\", database \"%s\".\n"),
-+ catalog->name(), catalog->db_name);
-+ if (db) {
-+ Jmsg(NULL, M_FATAL, 0, _("%s"), db_strerror(db));
-+ Pmsg1(000, "%s", db_strerror(db));
-+ db_close_database(NULL, db);
-+ }
-+
-+ } else { /* connection is OK */
-+ db_cleanup_job_record(NULL, db); /* check if jobs are running ?? */
-+ db_close_database(NULL, db);
-+ }
-+ }
-+}
-+
- static bool check_catalog()
- {
- bool OK = true;
-Index: src/cats/sql_update.c
-===================================================================
---- src/cats/sql_update.c (revision 7176)
-+++ src/cats/sql_update.c (working copy)
-@@ -288,6 +288,18 @@
- }
-
- bool
-+db_cleanup_job_record(JCR *jcr, B_DB *mdb)
-+{
-+ int stat;
-+ char query[] = "UPDATE Job SET JobStatus = 'f', EndTime = NOW() WHERE JobStatus IN ('R', 'C')";
-+
-+ db_lock(mdb);
-+ stat = UPDATE_DB(jcr, mdb, query);
-+ db_unlock(mdb);
-+ return stat;
-+}
-+
-+bool
- db_update_storage_record(JCR *jcr, B_DB *mdb, STORAGE_DBR *sr)
- {
- int stat;
-Index: src/cats/protos.h
-===================================================================
---- src/cats/protos.h (revision 7176)
-+++ src/cats/protos.h (working copy)
-@@ -123,6 +123,7 @@
- void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-
- /* sql_update.c */
-+bool db_cleanup_job_record(JCR *jcr, B_DB *mdb);
- bool db_update_job_start_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
- int db_update_job_end_record(JCR *jcr, B_DB *db, JOB_DBR *jr, bool stats_enabled);
- int db_update_client_record(JCR *jcr, B_DB *mdb, CLIENT_DBR *cr);
+++ /dev/null
---- bacula/src/dird/backup.c 2007-02-20 14:28:55.000000000 +0100
-+++ bacula.org/src/dird/backup.c 2007-02-20 14:27:54.000000000 +0100
-@@ -171,18 +171,6 @@
- set_jcr_job_status(jcr, JS_Running);
- fd = jcr->file_bsock;
-
-- if (!send_include_list(jcr)) {
-- goto bail_out;
-- }
--
-- if (!send_exclude_list(jcr)) {
-- goto bail_out;
-- }
--
-- if (!send_level_command(jcr)) {
-- goto bail_out;
-- }
--
- /*
- * send Storage daemon address to the File daemon
- */
-@@ -205,10 +193,24 @@
- goto bail_out;
- }
-
-+ /* setup job */
-+
-+ if (!send_level_command(jcr)) {
-+ goto bail_out;
-+ }
-+
- if (!send_runscripts_commands(jcr)) {
- goto bail_out;
- }
-
-+ if (!send_include_list(jcr)) {
-+ goto bail_out;
-+ }
-+
-+ if (!send_exclude_list(jcr)) {
-+ goto bail_out;
-+ }
-+
- /*
- * We re-update the job start record so that the start
- * time is set after the run before job. This avoids
+++ /dev/null
-From: Eric Bollengier <eric at homelinux dot org>
-
-This patch allow you to create include/exclude file list
-with ClientRunBeforeJob command.
-
-Job {
-...
- ClientRunBeforeJob = "gen_exclude.pl /tmp/lst.exc"
-}
-
-FileSet {
-...
- Include {
- File="\\</tmp/lst.exc"
- }
-}
+++ /dev/null
-
-This patch try to cleanup MaxConcurrent checks from director
-It's not usable yet.
-
-
-
-Index: src/dird/jobq.c
-===================================================================
---- src/dird/jobq.c (révision 6325)
-+++ src/dird/jobq.c (copie de travail)
-@@ -477,14 +477,14 @@
- * put into the ready queue.
- */
- if (jcr->acquired_resource_locks) {
-- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs = 0;
-- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-- }
-- if (jcr->wstore) {
-- jcr->wstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- }
-+// if (jcr->rstore) {
-+// jcr->rstore->NumConcurrentJobs = 0;
-+// Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-+// }
-+// if (jcr->wstore) {
-+// jcr->wstore->NumConcurrentJobs--;
-+// Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+// }
- jcr->client->NumConcurrentJobs--;
- jcr->job->NumConcurrentJobs--;
- jcr->acquired_resource_locks = false;
-@@ -678,69 +678,69 @@
- */
- static bool acquire_resources(JCR *jcr)
- {
-- bool skip_this_jcr = false;
--
-- jcr->acquired_resource_locks = false;
-- if (jcr->rstore) {
-- Dmsg1(200, "Rstore=%s\n", jcr->rstore->name());
-- /*
-- * Let only one Restore/Verify job run at a time regardless
-- * of MaxConcurrentjobs.
-- */
-- if (jcr->rstore->NumConcurrentJobs == 0) {
-- jcr->rstore->NumConcurrentJobs = 1;
-- Dmsg0(200, "Set rncj=1\n");
-- } else {
-- Dmsg1(200, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-- set_jcr_job_status(jcr, JS_WaitStoreRes);
-- return false;
-- }
-- }
--
-- if (jcr->wstore) {
-- Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
-- if (jcr->rstore == jcr->wstore) { /* deadlock */
-- jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
-- Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
-- " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"),
-- jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
-- set_jcr_job_status(jcr, JS_Canceled);
-- return false;
-- }
-- if (jcr->wstore->NumConcurrentJobs == 0 &&
-- jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
-- /* Simple case, first job */
-- jcr->wstore->NumConcurrentJobs = 1;
-- Dmsg0(200, "Set wncj=1\n");
-- } else if (jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
-- jcr->wstore->NumConcurrentJobs++;
-- Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- } else if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
-- Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- skip_this_jcr = true;
-- } else {
-- Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- skip_this_jcr = true;
-- }
-- }
-- if (skip_this_jcr) {
-- set_jcr_job_status(jcr, JS_WaitStoreRes);
-- return false;
-- }
--
-+// bool skip_this_jcr = false;
-+//
-+// jcr->acquired_resource_locks = false;
-+// if (jcr->rstore) {
-+// Dmsg1(200, "Rstore=%s\n", jcr->rstore->name());
-+// /*
-+// * Let only one Restore/Verify job run at a time regardless
-+// * of MaxConcurrentjobs.
-+// */
-+// if (jcr->rstore->NumConcurrentJobs == 0) {
-+// jcr->rstore->NumConcurrentJobs = 1;
-+// Dmsg0(200, "Set rncj=1\n");
-+// } else {
-+// Dmsg1(200, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-+// set_jcr_job_status(jcr, JS_WaitStoreRes);
-+// return false;
-+// }
-+// }
-+//
-+// if (jcr->wstore) {
-+// Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
-+// if (jcr->rstore == jcr->wstore) { /* deadlock */
-+// jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
-+// Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
-+// " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"),
-+// jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
-+// set_jcr_job_status(jcr, JS_Canceled);
-+// return false;
-+// }
-+// if (jcr->wstore->NumConcurrentJobs == 0 &&
-+// jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
-+// /* Simple case, first job */
-+// jcr->wstore->NumConcurrentJobs = 1;
-+// Dmsg0(200, "Set wncj=1\n");
-+// } else if (jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
-+// jcr->wstore->NumConcurrentJobs++;
-+// Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+// } else if (jcr->rstore) {
-+// jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
-+// Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+// skip_this_jcr = true;
-+// } else {
-+// Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+// skip_this_jcr = true;
-+// }
-+// }
-+// if (skip_this_jcr) {
-+// set_jcr_job_status(jcr, JS_WaitStoreRes);
-+// return false;
-+// }
-+//
- if (jcr->client->NumConcurrentJobs < jcr->client->MaxConcurrentJobs) {
- jcr->client->NumConcurrentJobs++;
- } else {
-- /* Back out previous locks */
-- if (jcr->wstore) {
-- jcr->wstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- }
-- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs = 0;
-- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-- }
-+// /* Back out previous locks */
-+// if (jcr->wstore) {
-+// jcr->wstore->NumConcurrentJobs--;
-+// Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+// }
-+// if (jcr->rstore) {
-+// jcr->rstore->NumConcurrentJobs = 0;
-+// Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-+// }
- set_jcr_job_status(jcr, JS_WaitClientRes);
- return false;
- }
-@@ -748,14 +748,14 @@
- jcr->job->NumConcurrentJobs++;
- } else {
- /* Back out previous locks */
-- if (jcr->wstore) {
-- jcr->wstore->NumConcurrentJobs--;
-- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-- }
-- if (jcr->rstore) {
-- jcr->rstore->NumConcurrentJobs = 0;
-- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-- }
-+// if (jcr->wstore) {
-+// jcr->wstore->NumConcurrentJobs--;
-+// Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
-+// }
-+// if (jcr->rstore) {
-+// jcr->rstore->NumConcurrentJobs = 0;
-+// Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
-+// }
- jcr->client->NumConcurrentJobs--;
- set_jcr_job_status(jcr, JS_WaitJobRes);
- return false;
+++ /dev/null
-Index: src/dird/ua_output.c
-===================================================================
---- src/dird/ua_output.c (revision 8203)
-+++ src/dird/ua_output.c (working copy)
-@@ -223,6 +223,7 @@
- * list clients - list clients
- * list nextvol job=xx - list the next vol to be used by job
- * list nextvolume job=xx - same as above.
-+ * list copies jobid=x,y,z
- *
- */
-
-@@ -454,6 +455,19 @@
- }
- }
- list_nextvol(ua, n);
-+ } else if (strcasecmp(ua->argk[i], NT_("copies")) == 0) {
-+ 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]) {
-+ if (is_a_number_list(ua->argv[j])) {
-+ jobids = ua->argv[j];
-+ }
-+ } else if (strcasecmp(ua->argk[j], NT_("limit")) == 0 && ua->argv[j]) {
-+ limit = atoi(ua->argv[j]);
-+ }
-+ }
-+ db_list_copies_records(ua->jcr,ua->db,limit,jobids,prtit,ua,llist);
- } else if (strcasecmp(ua->argk[i], NT_("limit")) == 0
- || strcasecmp(ua->argk[i], NT_("days")) == 0) {
- /* Ignore it */
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 8203)
-+++ src/dird/migrate.c (working copy)
-@@ -1158,13 +1158,17 @@
- /*
- * If we terminated a copy normally:
- * - copy any Log records to the new JobId
-+ * - set type="Job Copy" for the new job
- */
- if (jcr->get_JobType() == JT_COPY && jcr->JobStatus == JS_Terminated) {
- /* Copy JobLog to new JobId */
- Mmsg(query, "INSERT INTO Log (JobId, Time, LogText ) "
- "SELECT %s, Time, LogText FROM Log WHERE JobId=%s",
-- new_jobid, old_jobid);
-+ edit_uint64(mig_jcr->jr.JobId, ec7), old_jobid);
- db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
-+ Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s",
-+ (char)JT_JOB_COPY, ec7);
-+ db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
- }
-
- if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
-Index: src/dird/ua_purge.c
-===================================================================
---- src/dird/ua_purge.c (revision 8203)
-+++ src/dird/ua_purge.c (working copy)
-@@ -360,6 +360,57 @@
- }
-
- /*
-+ * Change the type of the next copy job to backup.
-+ * We need to upgrade the next copy of a normal job,
-+ * and also upgrade the next copy when the normal job
-+ * already have been purged.
-+ *
-+ * JobId: 1 PriorJobId: 0 (original)
-+ * JobId: 2 PriorJobId: 1 (first copy)
-+ * JobId: 3 PriorJobId: 1 (second copy)
-+ *
-+ * JobId: 2 PriorJobId: 1 (first copy, now regular backup)
-+ * JobId: 3 PriorJobId: 1 (second copy)
-+ *
-+ * => Search through PriorJobId in jobid and
-+ * PriorJobId in PriorJobId (jobid)
-+ */
-+void upgrade_copies(UAContext *ua, char *jobs)
-+{
-+ POOL_MEM query(PM_MESSAGE);
-+
-+ db_lock(ua->db);
-+ /* Do it in two times for mysql */
-+ Mmsg(query, "CREATE TEMPORARY TABLE cpy_tmp AS "
-+ "SELECT MIN(JobId) AS JobId FROM Job " /* Choose the oldest job */
-+ "WHERE Type='%c' "
-+ "AND ( PriorJobId IN (%s) "
-+ "OR "
-+ " PriorJobId IN ( "
-+ "SELECT PriorJobId "
-+ "FROM Job "
-+ "WHERE JobId IN (%s) "
-+ " AND Type='B' "
-+ ") "
-+ ") "
-+ "GROUP BY PriorJobId ", /* one result per copy */
-+ JT_JOB_COPY, jobs, jobs);
-+ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-+
-+ /* Now upgrade first copy to Backup */
-+ Mmsg(query, "UPDATE Job SET Type='B' " /* JT_JOB_COPY => JT_BACKUP */
-+ "WHERE JobId IN ( SELECT JobId FROM cpy_tmp )");
-+
-+ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-+
-+ Mmsg(query, "DROP TABLE cpy_tmp");
-+ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-+
-+ db_unlock(ua->db);
-+ Dmsg1(00, "Upgrade copies Log sql=%s\n", query.c_str());
-+}
-+
-+/*
- * Remove all records from catalog for a list of JobIds
- */
- void purge_jobs_from_catalog(UAContext *ua, char *jobs)
-@@ -377,13 +428,15 @@
- db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
- Dmsg1(050, "Delete Log sql=%s\n", query.c_str());
-
-+ upgrade_copies(ua, jobs);
-+
- /* Now remove the Job record itself */
- Mmsg(query, "DELETE FROM Job WHERE JobId IN (%s)", jobs);
- db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-+
- Dmsg1(050, "Delete Job sql=%s\n", query.c_str());
- }
-
--
- void purge_files_from_volume(UAContext *ua, MEDIA_DBR *mr )
- {} /* ***FIXME*** implement */
-
-Index: src/dird/ua_restore.c
-===================================================================
---- src/dird/ua_restore.c (revision 8203)
-+++ src/dird/ua_restore.c (working copy)
-@@ -444,6 +444,7 @@
- "add_suffix", /* 17 */
- "regexwhere", /* 18 */
- "restoreclient", /* 19 */
-+ "copies", /* 20 */
- NULL
- };
-
-@@ -1138,9 +1139,10 @@
- bool ok = false;
- FILESET_DBR fsr;
- CLIENT_DBR cr;
-+ POOL_MEM other_filter(PM_MESSAGE);
-+ POOL_MEM temp_filter(PM_MESSAGE);
- char fileset_name[MAX_NAME_LENGTH];
- char ed1[50], ed2[50];
-- char pool_select[MAX_NAME_LENGTH];
- int i;
-
- /* Create temp tables */
-@@ -1196,23 +1198,32 @@
- }
-
- /* If Pool specified, add PoolId specification */
-- pool_select[0] = 0;
- if (rx->pool) {
- POOL_DBR pr;
- memset(&pr, 0, sizeof(pr));
- bstrncpy(pr.Name, rx->pool->name(), sizeof(pr.Name));
- if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
-- bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ",
-- edit_int64(pr.PoolId, ed1));
-+ Mmsg(other_filter, " AND Media.PoolId=%s ",
-+ edit_int64(pr.PoolId, ed1));
- } else {
- ua->warning_msg(_("Pool \"%s\" not found, using any pool.\n"), pr.Name);
- }
- }
-+ /* include copies or not in job selection */
-+ if (find_arg(ua, NT_("copies")) > 0) {
-+ Mmsg(temp_filter, "%s AND Job.Type IN ('%c', '%c') ",
-+ other_filter.c_str(), (char)JT_BACKUP, (char)JT_JOB_COPY);
-+ } else {
-+ Mmsg(temp_filter, "%s AND Job.Type = '%c' ", other_filter.c_str(),
-+ (char)JT_BACKUP);
-+ }
-+ pm_strcpy(other_filter, temp_filter.c_str());
-
- /* Find JobId of last Full backup for this client, fileset */
- edit_int64(cr.ClientId, ed1);
- Mmsg(rx->query, uar_last_full, ed1, ed1, date, fsr.FileSet,
-- pool_select);
-+ other_filter.c_str());
-+ Dmsg1(0, "sql=%s\n", rx->query);
- if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
- ua->error_msg("%s\n", db_strerror(ua->db));
- goto bail_out;
-@@ -1238,12 +1249,13 @@
-
- /* Now find most recent Differental Job after Full save, if any */
- Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date,
-- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
-+ edit_int64(cr.ClientId, ed2), fsr.FileSet, other_filter.c_str());
- if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
- ua->warning_msg("%s\n", db_strerror(ua->db));
- }
- /* Now update JobTDate to lock onto Differental, if any */
- rx->JobTDate = 0;
-+ Dmsg1(0, "sql=%s\n", rx->query);
- if (!db_sql_query(ua->db, uar_sel_all_temp, last_full_handler, (void *)rx)) {
- ua->warning_msg("%s\n", db_strerror(ua->db));
- }
-@@ -1254,7 +1266,8 @@
-
- /* Now find all Incremental Jobs after Full/dif save */
- Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date,
-- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
-+ edit_int64(cr.ClientId, ed2), fsr.FileSet, other_filter.c_str());
-+ Dmsg1(0, "sql=%s\n", rx->query);
- if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
- ua->warning_msg("%s\n", db_strerror(ua->db));
- }
-@@ -1267,6 +1280,8 @@
- }
-
- if (rx->JobIds[0] != 0) {
-+ /* Display a list of all copies */
-+ db_list_copies_records(ua->jcr, ua->db, 0, rx->JobIds, prtit, ua, HORZ_LIST);
- /* Display a list of Jobs selected for this restore */
- db_list_sql_query(ua->jcr, ua->db, uar_list_temp, prtit, ua, 1, HORZ_LIST);
- ok = true;
-Index: src/dird/ua_cmds.c
-===================================================================
---- src/dird/ua_cmds.c (revision 8203)
-+++ src/dird/ua_cmds.c (working copy)
-@@ -123,7 +123,7 @@
- { NT_("exit"), quit_cmd, _("exit = quit"), false},
- { NT_("gui"), gui_cmd, _("gui [on|off] -- non-interactive gui mode"), false},
- { NT_("help"), help_cmd, _("print this command"), false},
-- { NT_("list"), list_cmd, _("list [pools | jobs | jobtotals | media <pool=pool-name> | files <jobid=nn>]; from catalog"), true},
-+ { NT_("list"), list_cmd, _("list [pools | jobs | jobtotals | media <pool=pool-name> | files <jobid=nn> | copies <jobid=nn>]; from catalog"), true},
- { NT_("label"), label_cmd, _("label a tape"), false},
- { NT_("llist"), llist_cmd, _("full or long list like list command"), true},
- { NT_("messages"), messagescmd, _("messages"), false},
-Index: src/cats/protos.h
-===================================================================
---- src/cats/protos.h (revision 8203)
-+++ src/cats/protos.h (working copy)
-@@ -124,6 +124,7 @@
- void db_list_joblog_records(JCR *jcr, B_DB *mdb, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
- int db_list_sql_query(JCR *jcr, B_DB *mdb, const char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type);
- void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-+void db_list_copies_records(JCR *jcr, B_DB *mdb, uint32_t limit, char *jobids, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-
- /* sql_update.c */
- bool db_update_job_start_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
-Index: src/cats/sql_cmds.c
-===================================================================
---- src/cats/sql_cmds.c (revision 8203)
-+++ src/cats/sql_cmds.c (working copy)
-@@ -286,7 +286,7 @@
- "FROM Client,Job,JobMedia,Media,FileSet WHERE Client.ClientId=%s "
- "AND Job.ClientId=%s "
- "AND Job.StartTime<'%s' "
-- "AND Level='F' AND JobStatus='T' AND Type='B' "
-+ "AND Level='F' AND JobStatus='T' "
- "AND JobMedia.JobId=Job.JobId "
- "AND Media.Enabled=1 "
- "AND JobMedia.MediaId=Media.MediaId "
-@@ -297,13 +297,14 @@
-
- const char *uar_full =
- "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,"
-- "Job.ClientId,Job.Level,Job.JobFiles,Job.JobBytes,"
-- "StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime "
-- "FROM temp1,Job,JobMedia,Media WHERE temp1.JobId=Job.JobId "
-- "AND Level='F' AND JobStatus='T' AND Type='B' "
-- "AND Media.Enabled=1 "
-- "AND JobMedia.JobId=Job.JobId "
-- "AND JobMedia.MediaId=Media.MediaId";
-+ "Job.ClientId,Job.Level,Job.JobFiles,Job.JobBytes,"
-+ "StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime "
-+ "FROM temp1,Job,JobMedia,Media "
-+ "WHERE temp1.JobId=Job.JobId "
-+ "AND Level='F' AND JobStatus='T' "
-+ "AND Media.Enabled=1 "
-+ "AND JobMedia.JobId=Job.JobId "
-+ "AND JobMedia.MediaId=Media.MediaId";
-
- const char *uar_dif =
- "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,Job.ClientId,"
-@@ -316,7 +317,7 @@
- "AND JobMedia.JobId=Job.JobId "
- "AND Media.Enabled=1 "
- "AND JobMedia.MediaId=Media.MediaId "
-- "AND Job.Level='D' AND JobStatus='T' AND Type='B' "
-+ "AND Job.Level='D' AND JobStatus='T' "
- "AND Job.FileSetId=FileSet.FileSetId "
- "AND FileSet.FileSet='%s' "
- "%s"
-@@ -333,7 +334,7 @@
- "AND Media.Enabled=1 "
- "AND JobMedia.JobId=Job.JobId "
- "AND JobMedia.MediaId=Media.MediaId "
-- "AND Job.Level='I' AND JobStatus='T' AND Type='B' "
-+ "AND Job.Level='I' AND JobStatus='T' "
- "AND Job.FileSetId=FileSet.FileSetId "
- "AND FileSet.FileSet='%s' "
- "%s";
-Index: src/cats/sql_list.c
-===================================================================
---- src/cats/sql_list.c (revision 8203)
-+++ src/cats/sql_list.c (working copy)
-@@ -242,6 +242,43 @@
- }
-
-
-+void db_list_copies_records(JCR *jcr, B_DB *mdb, uint32_t limit, char *JobIds,
-+ DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
-+{
-+ POOL_MEM str_limit(PM_MESSAGE);
-+ POOL_MEM str_jobids(PM_MESSAGE);
-+
-+ if (limit > 0) {
-+ Mmsg(str_limit, " LIMIT %d", limit);
-+ }
-+
-+ if (JobIds && JobIds[0]) {
-+ Mmsg(str_jobids, " AND (C.PriorJobId IN (%s) OR C.JobId IN (%s)) ",
-+ JobIds, JobIds);
-+ }
-+
-+ db_lock(mdb);
-+ Mmsg(mdb->cmd,
-+ "SELECT DISTINCT C.PriorJobId AS JobId, C.Job, "
-+ "C.JobId AS CopyJobId, M.MediaType "
-+ "FROM Job AS C "
-+ "JOIN JobMedia USING (JobId) "
-+ "JOIN Media AS M USING (MediaId) "
-+ "WHERE C.Type = '%c' %s ORDER BY C.PriorJobId DESC %s",
-+ (char) JT_JOB_COPY, str_jobids.c_str(), str_limit.c_str());
-+
-+ if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
-+ goto bail_out;
-+ }
-+
-+ list_result(jcr, mdb, sendit, ctx, type);
-+
-+ sql_free_result(mdb);
-+
-+bail_out:
-+ db_unlock(mdb);
-+}
-+
- void db_list_joblog_records(JCR *jcr, B_DB *mdb, uint32_t JobId,
- DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
- {
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (revision 8203)
-+++ src/jcr.h (working copy)
-@@ -60,11 +60,12 @@
- #define JT_MIGRATED_JOB 'M' /* A previous backup job that was migrated */
- #define JT_VERIFY 'V' /* Verify Job */
- #define JT_RESTORE 'R' /* Restore Job */
--#define JT_CONSOLE 'c' /* console program */
-+#define JT_CONSOLE 'U' /* console program */
- #define JT_SYSTEM 'I' /* internal system "job" */
- #define JT_ADMIN 'D' /* admin job */
- #define JT_ARCHIVE 'A' /* Archive Job */
--#define JT_COPY 'C' /* Copy Job */
-+#define JT_JOB_COPY 'C' /* Copy of a Job */
-+#define JT_COPY 'c' /* Copy Job */
- #define JT_MIGRATE 'g' /* Migration Job */
- #define JT_SCAN 'S' /* Scan Job */
-
-Index: src/lib/util.c
-===================================================================
---- src/lib/util.c (revision 8203)
-+++ src/lib/util.c (working copy)
-@@ -361,6 +361,9 @@
- case JT_COPY:
- str = _("Copy");
- break;
-+ case JT_JOB_COPY:
-+ str = _("Job Copy");
-+ break;
- case JT_CONSOLE:
- str = _("Console");
- break;
-Index: src/lib/protos.h
-===================================================================
---- src/lib/protos.h (revision 8203)
-+++ src/lib/protos.h (working copy)
-@@ -186,6 +186,7 @@
- bool size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
- char *edit_utime (utime_t val, char *buf, int buf_len);
- bool is_a_number (const char *num);
-+bool is_a_number_list (const char *n);
- bool is_an_integer (const char *n);
- bool is_name_valid (char *name, POOLMEM **msg);
-
-Index: src/lib/edit.c
-===================================================================
---- src/lib/edit.c (revision 8203)
-+++ src/lib/edit.c (working copy)
-@@ -407,6 +407,27 @@
- }
-
- /*
-+ * Check if specified string is a list of number or not
-+ */
-+bool is_a_number_list(const char *n)
-+{
-+ bool previous_digit = false;
-+ bool digit_seen = false;
-+ while (*n) {
-+ if (B_ISDIGIT(*n)) {
-+ previous_digit=true;
-+ digit_seen = true;
-+ } else if (*n == ',' && previous_digit) {
-+ previous_digit = false;
-+ } else {
-+ return false;
-+ }
-+ n++;
-+ }
-+ return digit_seen && *n==0;
-+}
-+
-+/*
- * Check if the specified string is an integer
- */
- bool is_an_integer(const char *n)
-Index: patches/testing/copy_list_copies_cmd.patch
-===================================================================
---- patches/testing/copy_list_copies_cmd.patch (revision 8203)
-+++ patches/testing/copy_list_copies_cmd.patch (working copy)
-@@ -1,26 +1,38 @@
- Index: src/dird/ua_output.c
- ===================================================================
----- src/dird/ua_output.c (revision 8163)
-+--- src/dird/ua_output.c (revision 8203)
- +++ src/dird/ua_output.c (working copy)
--@@ -454,6 +454,15 @@
-+@@ -223,6 +223,7 @@
-+ * list clients - list clients
-+ * list nextvol job=xx - list the next vol to be used by job
-+ * list nextvolume job=xx - same as above.
-++ * list copies jobid=x,y,z
-+ *
-+ */
-+
-+@@ -454,6 +455,19 @@
- }
- }
- list_nextvol(ua, n);
- + } else if (strcasecmp(ua->argk[i], NT_("copies")) == 0) {
-++ 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]) {
--+ jr.JobId = str_to_int64(ua->argv[j]);
-++ if (is_a_number_list(ua->argv[j])) {
-++ jobids = ua->argv[j];
-++ }
- + } else if (strcasecmp(ua->argk[j], NT_("limit")) == 0 && ua->argv[j]) {
--+ jr.limit = atoi(ua->argv[j]);
-++ limit = atoi(ua->argv[j]);
- + }
- + }
--+ db_list_copies_records(ua->jcr, ua->db, &jr, prtit, ua, llist);
-++ db_list_copies_records(ua->jcr,ua->db,limit,jobids,prtit,ua,llist);
- } else if (strcasecmp(ua->argk[i], NT_("limit")) == 0
- || strcasecmp(ua->argk[i], NT_("days")) == 0) {
- /* Ignore it */
- Index: src/dird/migrate.c
- ===================================================================
----- src/dird/migrate.c (revision 8179)
-+--- src/dird/migrate.c (revision 8203)
- +++ src/dird/migrate.c (working copy)
- @@ -1158,13 +1158,17 @@
- /*
-@@ -41,9 +53,183 @@
- }
-
- if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
-+Index: src/dird/ua_purge.c
-+===================================================================
-+--- src/dird/ua_purge.c (revision 8203)
-++++ src/dird/ua_purge.c (working copy)
-+@@ -360,6 +360,57 @@
-+ }
-+
-+ /*
-++ * Change the type of the next copy job to backup.
-++ * We need to upgrade the next copy of a normal job,
-++ * and also upgrade the next copy when the normal job
-++ * already have been purged.
-++ *
-++ * JobId: 1 PriorJobId: 0 (original)
-++ * JobId: 2 PriorJobId: 1 (first copy)
-++ * JobId: 3 PriorJobId: 1 (second copy)
-++ *
-++ * JobId: 2 PriorJobId: 1 (first copy, now regular backup)
-++ * JobId: 3 PriorJobId: 1 (second copy)
-++ *
-++ * => Search through PriorJobId in jobid and
-++ * PriorJobId in PriorJobId (jobid)
-++ */
-++void upgrade_copies(UAContext *ua, char *jobs)
-++{
-++ POOL_MEM query(PM_MESSAGE);
-++
-++ db_lock(ua->db);
-++ /* Do it in two times for mysql */
-++ Mmsg(query, "CREATE TEMPORARY TABLE cpy_tmp AS "
-++ "SELECT MIN(JobId) AS JobId FROM Job " /* Choose the oldest job */
-++ "WHERE Type='%c' "
-++ "AND ( PriorJobId IN (%s) "
-++ "OR "
-++ " PriorJobId IN ( "
-++ "SELECT PriorJobId "
-++ "FROM Job "
-++ "WHERE JobId IN (%s) "
-++ " AND Type='B' "
-++ ") "
-++ ") "
-++ "GROUP BY PriorJobId ", /* one result per copy */
-++ JT_JOB_COPY, jobs, jobs);
-++ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-++
-++ /* Now upgrade first copy to Backup */
-++ Mmsg(query, "UPDATE Job SET Type='B' " /* JT_JOB_COPY => JT_BACKUP */
-++ "WHERE JobId IN ( SELECT JobId FROM cpy_tmp )");
-++
-++ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-++
-++ Mmsg(query, "DROP TABLE cpy_tmp");
-++ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-++
-++ db_unlock(ua->db);
-++ Dmsg1(00, "Upgrade copies Log sql=%s\n", query.c_str());
-++}
-++
-++/*
-+ * Remove all records from catalog for a list of JobIds
-+ */
-+ void purge_jobs_from_catalog(UAContext *ua, char *jobs)
-+@@ -377,13 +428,15 @@
-+ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-+ Dmsg1(050, "Delete Log sql=%s\n", query.c_str());
-+
-++ upgrade_copies(ua, jobs);
-++
-+ /* Now remove the Job record itself */
-+ Mmsg(query, "DELETE FROM Job WHERE JobId IN (%s)", jobs);
-+ db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL);
-++
-+ Dmsg1(050, "Delete Job sql=%s\n", query.c_str());
-+ }
-+
-+-
-+ void purge_files_from_volume(UAContext *ua, MEDIA_DBR *mr )
-+ {} /* ***FIXME*** implement */
-+
-+Index: src/dird/ua_restore.c
-+===================================================================
-+--- src/dird/ua_restore.c (revision 8203)
-++++ src/dird/ua_restore.c (working copy)
-+@@ -444,6 +444,7 @@
-+ "add_suffix", /* 17 */
-+ "regexwhere", /* 18 */
-+ "restoreclient", /* 19 */
-++ "copies", /* 20 */
-+ NULL
-+ };
-+
-+@@ -1138,9 +1139,10 @@
-+ bool ok = false;
-+ FILESET_DBR fsr;
-+ CLIENT_DBR cr;
-++ POOL_MEM other_filter(PM_MESSAGE);
-++ POOL_MEM temp_filter(PM_MESSAGE);
-+ char fileset_name[MAX_NAME_LENGTH];
-+ char ed1[50], ed2[50];
-+- char pool_select[MAX_NAME_LENGTH];
-+ int i;
-+
-+ /* Create temp tables */
-+@@ -1196,23 +1198,32 @@
-+ }
-+
-+ /* If Pool specified, add PoolId specification */
-+- pool_select[0] = 0;
-+ if (rx->pool) {
-+ POOL_DBR pr;
-+ memset(&pr, 0, sizeof(pr));
-+ bstrncpy(pr.Name, rx->pool->name(), sizeof(pr.Name));
-+ if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
-+- bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ",
-+- edit_int64(pr.PoolId, ed1));
-++ Mmsg(other_filter, " AND Media.PoolId=%s ",
-++ edit_int64(pr.PoolId, ed1));
-+ } else {
-+ ua->warning_msg(_("Pool \"%s\" not found, using any pool.\n"), pr.Name);
-+ }
-+ }
-++ /* include copies or not in job selection */
-++ if (find_arg(ua, NT_("copies")) > 0) {
-++ Mmsg(temp_filter, "%s AND Job.Type IN ('%c', '%c') ",
-++ other_filter.c_str(), (char)JT_BACKUP, (char)JT_JOB_COPY);
-++ } else {
-++ Mmsg(temp_filter, "%s AND Job.Type = '%c' ", other_filter.c_str(),
-++ (char)JT_BACKUP);
-++ }
-++ pm_strcpy(other_filter, temp_filter.c_str());
-+
-+ /* Find JobId of last Full backup for this client, fileset */
-+ edit_int64(cr.ClientId, ed1);
-+ Mmsg(rx->query, uar_last_full, ed1, ed1, date, fsr.FileSet,
-+- pool_select);
-++ other_filter.c_str());
-++ Dmsg1(0, "sql=%s\n", rx->query);
-+ if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
-+ ua->error_msg("%s\n", db_strerror(ua->db));
-+ goto bail_out;
-+@@ -1238,12 +1249,13 @@
-+
-+ /* Now find most recent Differental Job after Full save, if any */
-+ Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date,
-+- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
-++ edit_int64(cr.ClientId, ed2), fsr.FileSet, other_filter.c_str());
-+ if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
-+ ua->warning_msg("%s\n", db_strerror(ua->db));
-+ }
-+ /* Now update JobTDate to lock onto Differental, if any */
-+ rx->JobTDate = 0;
-++ Dmsg1(0, "sql=%s\n", rx->query);
-+ if (!db_sql_query(ua->db, uar_sel_all_temp, last_full_handler, (void *)rx)) {
-+ ua->warning_msg("%s\n", db_strerror(ua->db));
-+ }
-+@@ -1254,7 +1266,8 @@
-+
-+ /* Now find all Incremental Jobs after Full/dif save */
-+ Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date,
-+- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
-++ edit_int64(cr.ClientId, ed2), fsr.FileSet, other_filter.c_str());
-++ Dmsg1(0, "sql=%s\n", rx->query);
-+ if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
-+ ua->warning_msg("%s\n", db_strerror(ua->db));
-+ }
-+@@ -1267,6 +1280,8 @@
-+ }
-+
-+ if (rx->JobIds[0] != 0) {
-++ /* Display a list of all copies */
-++ db_list_copies_records(ua->jcr, ua->db, 0, rx->JobIds, prtit, ua, HORZ_LIST);
-+ /* Display a list of Jobs selected for this restore */
-+ db_list_sql_query(ua->jcr, ua->db, uar_list_temp, prtit, ua, 1, HORZ_LIST);
-+ ok = true;
- Index: src/dird/ua_cmds.c
- ===================================================================
----- src/dird/ua_cmds.c (revision 8163)
-+--- src/dird/ua_cmds.c (revision 8203)
- +++ src/dird/ua_cmds.c (working copy)
- @@ -123,7 +123,7 @@
- { NT_("exit"), quit_cmd, _("exit = quit"), false},
-@@ -56,48 +242,101 @@
- { NT_("messages"), messagescmd, _("messages"), false},
- Index: src/cats/protos.h
- ===================================================================
----- src/cats/protos.h (revision 8163)
-+--- src/cats/protos.h (revision 8203)
- +++ src/cats/protos.h (working copy)
- @@ -124,6 +124,7 @@
- void db_list_joblog_records(JCR *jcr, B_DB *mdb, JobId_t JobId, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
- int db_list_sql_query(JCR *jcr, B_DB *mdb, const char *query, DB_LIST_HANDLER *sendit, void *ctx, int verbose, e_list_type type);
- void db_list_client_records(JCR *jcr, B_DB *mdb, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
--+void db_list_copies_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-++void db_list_copies_records(JCR *jcr, B_DB *mdb, uint32_t limit, char *jobids, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type);
-
- /* sql_update.c */
- bool db_update_job_start_record(JCR *jcr, B_DB *db, JOB_DBR *jr);
-+Index: src/cats/sql_cmds.c
-+===================================================================
-+--- src/cats/sql_cmds.c (revision 8203)
-++++ src/cats/sql_cmds.c (working copy)
-+@@ -286,7 +286,7 @@
-+ "FROM Client,Job,JobMedia,Media,FileSet WHERE Client.ClientId=%s "
-+ "AND Job.ClientId=%s "
-+ "AND Job.StartTime<'%s' "
-+- "AND Level='F' AND JobStatus='T' AND Type='B' "
-++ "AND Level='F' AND JobStatus='T' "
-+ "AND JobMedia.JobId=Job.JobId "
-+ "AND Media.Enabled=1 "
-+ "AND JobMedia.MediaId=Media.MediaId "
-+@@ -297,13 +297,14 @@
-+
-+ const char *uar_full =
-+ "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,"
-+- "Job.ClientId,Job.Level,Job.JobFiles,Job.JobBytes,"
-+- "StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime "
-+- "FROM temp1,Job,JobMedia,Media WHERE temp1.JobId=Job.JobId "
-+- "AND Level='F' AND JobStatus='T' AND Type='B' "
-+- "AND Media.Enabled=1 "
-+- "AND JobMedia.JobId=Job.JobId "
-+- "AND JobMedia.MediaId=Media.MediaId";
-++ "Job.ClientId,Job.Level,Job.JobFiles,Job.JobBytes,"
-++ "StartTime,VolumeName,JobMedia.StartFile,VolSessionId,VolSessionTime "
-++ "FROM temp1,Job,JobMedia,Media "
-++ "WHERE temp1.JobId=Job.JobId "
-++ "AND Level='F' AND JobStatus='T' "
-++ "AND Media.Enabled=1 "
-++ "AND JobMedia.JobId=Job.JobId "
-++ "AND JobMedia.MediaId=Media.MediaId";
-+
-+ const char *uar_dif =
-+ "INSERT INTO temp SELECT Job.JobId,Job.JobTDate,Job.ClientId,"
-+@@ -316,7 +317,7 @@
-+ "AND JobMedia.JobId=Job.JobId "
-+ "AND Media.Enabled=1 "
-+ "AND JobMedia.MediaId=Media.MediaId "
-+- "AND Job.Level='D' AND JobStatus='T' AND Type='B' "
-++ "AND Job.Level='D' AND JobStatus='T' "
-+ "AND Job.FileSetId=FileSet.FileSetId "
-+ "AND FileSet.FileSet='%s' "
-+ "%s"
-+@@ -333,7 +334,7 @@
-+ "AND Media.Enabled=1 "
-+ "AND JobMedia.JobId=Job.JobId "
-+ "AND JobMedia.MediaId=Media.MediaId "
-+- "AND Job.Level='I' AND JobStatus='T' AND Type='B' "
-++ "AND Job.Level='I' AND JobStatus='T' "
-+ "AND Job.FileSetId=FileSet.FileSetId "
-+ "AND FileSet.FileSet='%s' "
-+ "%s";
- Index: src/cats/sql_list.c
- ===================================================================
----- src/cats/sql_list.c (revision 8163)
-+--- src/cats/sql_list.c (revision 8203)
- +++ src/cats/sql_list.c (working copy)
- @@ -242,6 +242,43 @@
- }
-
-
--+void db_list_copies_records(JCR *jcr, B_DB *mdb, JOB_DBR *jr,
-++void db_list_copies_records(JCR *jcr, B_DB *mdb, uint32_t limit, char *JobIds,
- + DB_LIST_HANDLER *sendit, void *ctx, e_list_type type)
- +{
--+ char ed1[50];
--+ POOL_MEM limit(PM_MESSAGE);
--+ POOL_MEM jobids(PM_MESSAGE);
-++ POOL_MEM str_limit(PM_MESSAGE);
-++ POOL_MEM str_jobids(PM_MESSAGE);
- +
--+ if (jr->limit > 0) {
--+ Mmsg(limit, " LIMIT %d", jr->limit);
-++ if (limit > 0) {
-++ Mmsg(str_limit, " LIMIT %d", limit);
- + }
- +
--+ if (jr->JobId) {
--+ Mmsg(jobids, " AND (C.PriorJobId = %s OR C.JobId = %s) ",
--+ edit_int64(jr->JobId, ed1),ed1);
-++ if (JobIds && JobIds[0]) {
-++ Mmsg(str_jobids, " AND (C.PriorJobId IN (%s) OR C.JobId IN (%s)) ",
-++ JobIds, JobIds);
- + }
- +
- + db_lock(mdb);
- + Mmsg(mdb->cmd,
--+ "SELECT C.PriorJobId AS JobId, C.Job, C.JobId AS CopyJobId, M.MediaType "
-++ "SELECT DISTINCT C.PriorJobId AS JobId, C.Job, "
-++ "C.JobId AS CopyJobId, M.MediaType "
- + "FROM Job AS C "
- + "JOIN JobMedia USING (JobId) "
- + "JOIN Media AS M USING (MediaId) "
- + "WHERE C.Type = '%c' %s ORDER BY C.PriorJobId DESC %s",
--+ (char) JT_JOB_COPY, jobids.c_str(), limit.c_str());
-++ (char) JT_JOB_COPY, str_jobids.c_str(), str_limit.c_str());
- +
- + if (!QUERY_DB(jcr, mdb, mdb->cmd)) {
- + goto bail_out;
-@@ -116,7 +355,7 @@
- {
- Index: src/jcr.h
- ===================================================================
----- src/jcr.h (revision 8163)
-+--- src/jcr.h (revision 8203)
- +++ src/jcr.h (working copy)
- @@ -60,11 +60,12 @@
- #define JT_MIGRATED_JOB 'M' /* A previous backup job that was migrated */
-@@ -135,7 +374,7 @@
-
- Index: src/lib/util.c
- ===================================================================
----- src/lib/util.c (revision 8163)
-+--- src/lib/util.c (revision 8203)
- +++ src/lib/util.c (working copy)
- @@ -361,6 +361,9 @@
- case JT_COPY:
-@@ -147,3 +386,47 @@
- case JT_CONSOLE:
- str = _("Console");
- break;
-+Index: src/lib/protos.h
-+===================================================================
-+--- src/lib/protos.h (revision 8203)
-++++ src/lib/protos.h (working copy)
-+@@ -186,6 +186,7 @@
-+ bool size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
-+ char *edit_utime (utime_t val, char *buf, int buf_len);
-+ bool is_a_number (const char *num);
-++bool is_a_number_list (const char *n);
-+ bool is_an_integer (const char *n);
-+ bool is_name_valid (char *name, POOLMEM **msg);
-+
-+Index: src/lib/edit.c
-+===================================================================
-+--- src/lib/edit.c (revision 8203)
-++++ src/lib/edit.c (working copy)
-+@@ -407,6 +407,27 @@
-+ }
-+
-+ /*
-++ * Check if specified string is a list of number or not
-++ */
-++bool is_a_number_list(const char *n)
-++{
-++ bool previous_digit = false;
-++ bool digit_seen = false;
-++ while (*n) {
-++ if (B_ISDIGIT(*n)) {
-++ previous_digit=true;
-++ digit_seen = true;
-++ } else if (*n == ',' && previous_digit) {
-++ previous_digit = false;
-++ } else {
-++ return false;
-++ }
-++ n++;
-++ }
-++ return digit_seen && *n==0;
-++}
-++
-++/*
-+ * Check if the specified string is an integer
-+ */
-+ bool is_an_integer(const char *n)
-Index: patches/testing/fix_1190.patch
-===================================================================
---- patches/testing/fix_1190.patch (revision 8203)
-+++ patches/testing/fix_1190.patch (working copy)
-@@ -201,7 +201,6 @@
- }
- -// Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
- -// volblock->sblock, volblock->eblock, rec->Block);
--- if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
- + Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
- + volblock->sblock, volblock->eblock, rec->Block);
- +
-@@ -213,8 +212,8 @@
- + * But, we are already decoding rec->Block-1Block records
- + */
- + uint32_t max = volblock->eblock+DEFAULT_BLOCK_SIZE;
--+// if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
--+ if (min <= rec->Block && max >= rec->Block) {
-+ if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
-++// if (min <= rec->Block && max >= rec->Block) {
- return 1;
- }
- /* Once we get past last eblock, we are done */
-@@ -288,3 +287,23 @@
- }
- /*
- * Check for Start or End of Session Record
-+Index: block.c
-+===================================================================
-+--- block.c (révision 8116)
-++++ block.c (copie de travail)
-+@@ -1116,11 +1116,12 @@
-+ dcr->EndBlock = dev->EndBlock;
-+ dcr->EndFile = dev->EndFile;
-+ } else {
-+- uint64_t addr = dev->file_addr + block->read_len - 1;
-++ uint32_t len = MIN(block->read_len, block->block_len);
-++ uint64_t addr = dev->file_addr + len - 1;
-+ dcr->EndBlock = (uint32_t)addr;
-+ dcr->EndFile = (uint32_t)(addr >> 32);
-+- dev->block_num = dcr->EndBlock;
-+- dev->file = dcr->EndFile;
-++ dev->block_num = dev->EndBlock = dcr->EndBlock;
-++ dev->file = dev->EndFile = dcr->EndFile;
-+ }
-+ dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
-+ dev->file_addr += block->read_len;
-Index: patches/testing/find_smallest_volfile.patch
-===================================================================
---- patches/testing/find_smallest_volfile.patch (revision 8203)
-+++ patches/testing/find_smallest_volfile.patch (working copy)
-@@ -149,74 +149,3 @@
- return return_bsr;
- }
-
--@@ -386,8 +397,6 @@
-- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
-- goto no_match;
-- }
--- Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n",
--- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
--
-- if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) {
-- Dmsg2(dbglevel, "Fail on sesstime. bsr=%u rec=%u\n",
--@@ -411,6 +420,9 @@
-- Dmsg3(dbglevel, "match on findex=%d. bsr=%d,%d\n",
-- rec->FileIndex, bsr->FileIndex->findex, bsr->FileIndex->findex2);
--
--+ Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n",
--+ rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
--+
-- if (!match_fileregex(bsr, rec, jcr)) {
-- Dmsg1(dbglevel, "Fail on fileregex='%s'\n", bsr->fileregex);
-- goto no_match;
--@@ -607,14 +619,7 @@
--
-- static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done)
-- {
--- /*
--- * Currently block matching does not work correctly for disk
--- * files in all cases, so it is "turned off" by the following
--- * return statement.
--- */
--- return 1;
--
---
-- if (!volblock) {
-- return 1; /* no specification matches all */
-- }
--@@ -622,8 +627,9 @@
-- if (rec->state & REC_ISTAPE) {
-- return 1; /* All File records OK for this match */
-- }
---// Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
---// volblock->sblock, volblock->eblock, rec->Block);
--+ Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
--+ volblock->sblock, volblock->eblock, rec->Block);
--+
-- if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
-- return 1;
-- }
--Index: src/stored/read_record.c
--===================================================================
----- src/stored/read_record.c (révision 8116)
--+++ src/stored/read_record.c (copie de travail)
--@@ -261,8 +261,8 @@
-- Dmsg2(100, "All done=(file:block) %u:%u\n", dev->file, dev->block_num);
-- break;
-- } else if (rec->match_stat == 0) { /* no match */
--- Dmsg4(100, "BSR no match: clear rem=%d FI=%d before set_eof pos %u:%u\n",
--- rec->remainder, rec->FileIndex, dev->file, dev->block_num);
--+ Dmsg7(100, "BSR no match: clear rem=%d FI=%d rec->Block=%d dev->LastBlock=%d dev->EndBlock=%d before set_eof pos %u:%u\n",
--+ rec->remainder, rec->FileIndex, rec->Block, dev->LastBlock, dev->EndBlock, dev->file, dev->block_num);
-- rec->remainder = 0;
-- rec->state &= ~REC_PARTIAL_RECORD;
-- if (try_repositioning(jcr, rec, dcr)) {
--@@ -346,6 +346,9 @@
-- */
-- if (dev->file > bsr->volfile->sfile ||
-- (dev->file == bsr->volfile->sfile && dev->block_num > bsr->volblock->sblock)) {
--+ Dmsg4(dbglvl, _("Reposition from (file:block) %u:%u to %u:%u\n"),
--+ dev->file, dev->block_num, bsr->volfile->sfile,
--+ bsr->volblock->sblock);
-- return false;
-- }
-- if (verbose) {
+++ /dev/null
-
- This patch add a new protocol between storage and director
- to be able to guess device organisation.
-
-
-Index: src/dird/ua_cmds.c
-===================================================================
---- src/dird/ua_cmds.c (révision 8483)
-+++ src/dird/ua_cmds.c (copie de travail)
-@@ -98,6 +98,7 @@
- static int var_cmd(UAContext *ua, const char *cmd);
- static int version_cmd(UAContext *ua, const char *cmd);
- static int wait_cmd(UAContext *ua, const char *cmd);
-+static int devicegroup_cmd(UAContext *ua, const char *command);
-
- static void do_job_delete(UAContext *ua, JobId_t JobId);
- static void delete_job_id_range(UAContext *ua, char *tok);
-@@ -154,6 +155,7 @@
- { NT_("var"), var_cmd, _("does variable expansion"), false},
- { NT_("version"), version_cmd, _("print Director version"), true},
- { NT_("wait"), wait_cmd, _("wait [<jobname=name> | <jobid=nnn> | <ujobid=complete_name>] -- wait until no jobs are running"), false},
-+ { NT_("dg"), devicegroup_cmd, _(""), false}
- };
- #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
-
-@@ -1557,6 +1559,65 @@
- jcr->store_bsock = NULL;
- }
-
-+
-+static int devicegroup_cmd(UAContext *ua, const char *command)
-+{
-+ USTORE store;
-+ BSOCK *sd;
-+ JCR *jcr = ua->jcr;
-+ char dev_name[MAX_NAME_LENGTH];
-+ POOL_MEM devname;
-+ STORE *storage;
-+ DEVICE *dev;
-+
-+ if (!open_client_db(ua)) {
-+ return 1;
-+ }
-+ Dmsg2(120, "%s: %s\n", command, ua->UA_sock->msg);
-+
-+ store.store = get_storage_resource(ua, true/*arg is storage*/);
-+ if (!store.store) {
-+ return 1;
-+ }
-+ pm_strcpy(store.store_source, _("unknown source"));
-+ set_wstorage(jcr, &store);
-+
-+ if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) {
-+ ua->error_msg(_("Failed to connect to Storage daemon.\n"));
-+ return 1;
-+ }
-+ sd = jcr->store_bsock;
-+ bstrncpy(dev_name, store.store->dev_name(), sizeof(dev_name));
-+ bash_spaces(dev_name);
-+ bnet_fsend(sd, "devicegroup storage=%s", dev_name);
-+
-+ /* can construct a list of device name */
-+ while (bnet_recv(sd) >= 0) {
-+ if (sscanf(sd->msg, "dev=%127s", devname.c_str()) == 1) {
-+ unbash_spaces(devname);
-+
-+ /* get the device name from the storage resource */
-+ foreach_res(storage, R_STORAGE) {
-+ /* check that this resource is on the same storage */
-+ if (bstrcmp(store.store->address, storage->address) &&
-+ store.store->SDport == storage->SDport)
-+ {
-+
-+ foreach_alist(dev, storage->device) {
-+ if (bstrcmp(dev->name(), devname.c_str())) {
-+ ua->send_msg("%s\n", storage->name());
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ bnet_sig(sd, BNET_TERMINATE);
-+ bnet_close(sd);
-+ jcr->store_bsock = NULL;
-+ return 1;
-+}
-+
- /*
- * mount [storage=<name>] [drive=nn] [slot=mm]
- */
-Index: src/stored/dircmd.c
-===================================================================
---- src/stored/dircmd.c (révision 8483)
-+++ src/stored/dircmd.c (copie de travail)
-@@ -91,6 +91,7 @@
- int Slot, int relabel);
- static bool try_autoload_device(JCR *jcr, DCR *dcr, int slot, const char *VolName);
- static void send_dir_busy_message(BSOCK *dir, DEVICE *dev);
-+static bool devicegroup_cmd(JCR *jcr);
-
- struct s_cmds {
- const char *cmd;
-@@ -118,6 +119,7 @@
- {"unmount", unmount_cmd, 0},
- {"use storage=", use_cmd, 0},
- {"run", run_cmd, 0},
-+ {"devicegroup", devicegroup_cmd, 0},
- // {"query", query_cmd, 0},
- {NULL, NULL} /* list terminator */
- };
-@@ -629,6 +631,45 @@
-
-
- /*
-+ * devicegroup storage=<name>
-+ */
-+static bool devicegroup_cmd(JCR *jcr)
-+{
-+ POOL_MEM devname, result;
-+ BSOCK *dir = jcr->dir_bsock;
-+ AUTOCHANGER *ach;
-+ DEVRES *dev;
-+ DCR *dcr;
-+
-+ bool ok = sscanf(dir->msg, "devicegroup storage=%127s", devname.c_str()) == 1;
-+ if (ok) {
-+ dcr = find_device(jcr, devname, -1);
-+ if (dcr) {
-+ ach = dcr->device->changer_res;
-+ if (ach) {
-+ /* Send the autochanger name as device*/
-+ pm_strcpy(devname, ach->hdr.name);
-+ bash_spaces(devname);
-+ dir->fsend("dev=%s\n", devname.c_str());
-+
-+ /* Send all autochanger devices */
-+ foreach_alist(dev, ach->device) {
-+ pm_strcpy(devname, dev->hdr.name);
-+ bash_spaces(devname);
-+ dir->fsend("dev=%s\n", devname.c_str());
-+ }
-+ } else { /* if it's not an autochanger, just return it */
-+ pm_strcpy(devname, dcr->device->hdr.name);
-+ bash_spaces(devname);
-+ dir->fsend("dev=%s\n", devname.c_str());
-+ }
-+ }
-+ }
-+ dir->signal(BNET_EOD);
-+ return true;
-+}
-+
-+/*
- * Mount command from Director
- */
- static bool mount_cmd(JCR *jcr)
+++ /dev/null
-Idees
-------
-
-Addr
- x Use VolAddr in jobmedia
-
-Despool attributes later
- - use spool_attribute parameter (0,1,2)
- foreach spool_file (spool_files)
- ask to director ok/discard
- despool_attr
- end_of_despool
-
-Continious Backup Linux
- - stap
-http://www.redhat.com/magazine/011sep05/features/systemtap/
-http://sourceware.org/systemtap/
-
-Deduplication:
- proba de collision en fonction de la taille du hash
- http://en.wikipedia.org/wiki/Birthday_attack
-
-Cryptage :
- - Pouvoir configurer les algos de cryptage
- - Pouvoir choisir de crypter dans le fileset
- - Pouvoir choisir de forcer le cryptage dans la definition
- du client.
-
-Lister les fichiers sur le client :
- - Avoir un mode comme restore
- - Avoir une api list files client=xxx where=yyy
- Dans la filed/job.c:handle_client_request, ajouter une commande
- dans struct s_cmds cmds; et si possible utiliser le code de finlib
- - A voir, pourquoi ne pas utiliser mark/unmark comme dans une resto
- pour construire un fileset ?
-
-Sauvegarde des postes nomades :
- - Le client doit pouvoir initier les sauvegardes
- - Au niveau firewall, il ne doit y avoir que 1 connexion (1)
-
-
- Localhost |
- | +-------+ (4) +---------------+
- | | |<----| |
-+--------+ (5) +-------+ | | | | DIRECTOR |
-| |<------+ | | | |---->| |
-| FD | | PROXY | | | PROXY | (3) +-------+-------+
-| +-------> <-+---> | |
-+--------+ (6) +-^-----+ (2) | | +-------v-------+
- /-\ | | | (7) | |
- | | | +-----> STORAGE |
- | | | | | |
- Initiate backup | | +-------+ +---------------+
- --------------+ |
- (1) Network
-
-
-(1) & (2) BEGIN Backup
-(3) Bconsole like - Run command
-(4) & (5) DIR -> (PROX <-> PROX) -> FD connection (fileset, storage..)
-(6) & (7) FD -> (PROX <-> PROX) -> SD
-
- - Utilisation d'une sorte proxy https
-
-
-Bconsole :
- p Ajouter l'historique dans la bconsole
- - Ajouter une commande pour bloquer un drive
- - Ajouter de la completion automatique sur les commandes
-
-Sauvegarde SAN :
- - Avoir un SD sur chaque FD
- - Avoir une serie de script qui :
- * bascule le lecteur en local
- * lance le SD
- * le script de mtx doit faire ses demandes au director sur
- un autochanger commun
-
- - Tout le monde voit le lecteur, et le client doit demander la permission
- pour despooler son bloc de XG au director.
-
- - On fait du round robbin avec tout le monde, et on utilise un disque
- local pour spooler.
-
- - 50 clients qui spoolent en local, c'est plus rapide que vers 1 point
- central
-
-
-Gestion des stats :
- - Ajouter la gestion des stats dans le client et le sd
- - Ajouter un M_STATS dans la gestion des messages
- - générer un format simple UNIXSTAMP|label|unit|value
- - possibilité d'ajouter ça dans la base de donnée ou dans rrd
-
-Exchange backup:
-http://www.petri.co.il/brick_level_backup_of_mailboxes_by_using_exmerge.htm
-
-API :
-
- - apr (apache portable runtime) pour les exemples de chargement
- de module dynamique (win32, linux, etc...)
- http://svn.apache.org/viewvc/apr/apr/trunk/dso/
-
- - exemple apache
- http://modules.apache.org/doc/API.html
-
- - comment charger les librairies dependantes d'un hook
- ex: ACL -> -lacl
- GZIP -> -lgz
-
- - nommer les hook (a la place d'une structure de pointeur)
- ex:
- "action", mod_action_handler
-
- - interface
- - opendir
- - readdir
- - closedir
- - mkdir
- - stat
- - open
- - close
- - read
- - write
- - seek
- - get_perm
- - set_perm
- - configuration... (ajout automatique avant de charger le fichier de conf)
- - init
- - destroy
-
- - version
- - name
-
- - exemple de hook/module
- - cryptage ?
- - checksum (MD5/SHA1)
- - ACL/droits
- - compression (LZO, GZIP, BZIP)
-
- - initialiser le jcr avec seulement les hooks utiles
-
- - configuration
- - declarer les modules utiles
- - les options doivent utiliser le nom du module
- ex:
- GZIP level = 2
- ACL use uid = yes
- etc...
-
-TODO
-----
-
-bweb :
- - Support sqlite
- SELECT strftime('%Y-%m-%d', Job.StartTime) FROM Job LIMIT 1;
- x Voir les groupes d'un client
- - Overview, pouvoir choisir entre la job_old et l'autre
- - utiliser des noms de table plus proche (brestore -> bweb ?)
- x Balloon
-Btw., the vertical axis was the number of files
-while the size of the ballon is the volume (in MB
-or GB). Those could be switched, though, depending on what looks better.
-
-What are you using for color-coding the ballons?
-That could be a variety of different things like
-client, client group, backup level (full,
-incremental, etc.,) that adds context to the size
-and position that is already present in the chart.
-
- x Ajouter mount,umount,release,status pour chaque device
- - Ajouter le viewfileset dans l'interface de resto
- x Ajouter la labelisation de bande et l'ajout de media (add et label)
- - Ajouter la possibilité de lancer des migrations et des
- verification.
- - Quand on deplace un media, il faut prendre le enabled depuis
- la nouvelle localisation (en javascript)
- o On ajoute une combo (Backup/Migration/Verify)
- o On peut regarder dans l'historique des job quel est le bon type
- o Quand on relance, on spécifie le type directement
- o Il faut adapter le status client pour traiter les autres type
- de job (par exemple, si c'est pas un backup/restore, pas de status dir)
-
-
- x Ajouter une vue par groupe et par date (sur 7, 15 ou 30 jours)
-
- lu ma me je ve sa di
- groupe1 v v x w v v v q1
- |-- s1 v v v v v v v q2
- |-- s2 v v x v v v v
- `-- s3 v v v w v v v
-
----8<-------8<--------8<--------8<----------8<------------------
-
-ALTER TABLE Status ADD COLUMN severity int;
-UPDATE status SET severity = 15;
-UPDATE status SET severity = 100 where jobstatus = 'f';
-UPDATE status SET severity = 90 where jobstatus = 'A';
-UPDATE status SET severity = 10 where jobstatus = 'T';
-
--- Affiche par groupe et date le statut des jobs (q1)
-SELECT date_part('day', date) AS day, date, client_group_name, JobStatusLong,
- JobStatus, nb_job, joberrors
-FROM (
- SELECT date_trunc('day', job_old.StartTime) AS date,
- MAX(severity) AS severity,
- COUNT(1) AS nb_job,
- SUM(JobErrors) AS joberrors,
- client_group_name
- FROM job_old
- JOIN client_group_member USING (ClientId)
- JOIN client_group USING (client_group_id)
- JOIN Status USING (JobStatus)
- WHERE StartTime > '2007-10-01' AND StartTime < '2007-11-19'
-
- GROUP BY client_group_name, date
-) AS sub JOIN Status USING (severity)
- ORDER BY client_group_name, date
-
--- Affiche un client_group en detail (q2)
-SELECT date, client, JobStatusLong, JobStatus, nb_job, joberrors
-FROM (
- SELECT date_trunc('day', job_old.StartTime) AS date,
- Client.Name AS client,
- MAX(severity) AS severity,
- COUNT(1) AS nb_job,
- SUM(JobErrors) AS joberrors
- FROM job_old
- JOIN client_group_member USING (ClientId)
- JOIN client_group USING (client_group_id)
- JOIN Client USING (ClientId)
- JOIN Status USING (JobStatus)
- WHERE StartTime > '2007-10-01'
- AND client_group_name = '0-SAVES_SIGMA1'
-
- GROUP BY client, date
-) AS sub JOIN Status USING (severity)
- ORDER BY client, date
-
----8<-------8<--------8<--------8<----------8<------------------
-
- - Quand on clique dessus on arrive sur la liste des jobs en question
- Groupe -> Jobs
- Job -> Log
-
- x Ajouter une variable pour remplacer NOW() dans les queries
- origin = arg->{origin} || NOW();
- - Ajouter des stats en %
-
----8<-------8<--------8<--------8<----------8<------------------
-
-SELECT client_group_name, (nb_ok::float/(nb_ok+nb_other)*100)::numeric(6,3) AS percent_ok
-FROM (
-
- SELECT
- SUM(CASE WHEN JobStatus='T' THEN 1
- ELSE 0 END) AS nb_ok,
- SUM(CASE WHEN JobStatus='A' THEN 1
- WHEN JobStatus='f' THEN 1
- WHEN JobStatus='E' THEN 1
- WHEN JobStatus='e' THEN 1
- ELSE 0 END) AS nb_other,
- client_group_name
- FROM job_old
- JOIN client_group_member USING (ClientId)
- JOIN client_group USING (client_group_id)
-
- WHERE StartTime > '2007-10-01'
- GROUP BY client_group_name
-) AS subq
-
-SELECT Name, (nb_ok::float/(nb_ok+nb_other)*100)::numeric(6,3) AS percent_ok
-FROM (
-
- SELECT
- SUM(CASE WHEN JobStatus='T' THEN 1
- ELSE 0 END) AS nb_ok,
- SUM(CASE WHEN JobStatus='A' THEN 1
- WHEN JobStatus='f' THEN 1
- WHEN JobStatus='E' THEN 1
- WHEN JobStatus='e' THEN 1
- ELSE 0 END) AS nb_other,
- Client.Name AS name
- FROM job_old
- JOIN Client USING (ClientId)
-
- WHERE StartTime > '2007-10-01'
- AND JobStatus IN ('T', 'A', 'f', 'E', 'e')
- GROUP BY Client.Name
-) AS subq
-
-
-
----8<-------8<--------8<--------8<----------8<------------------
-
- Nb backup OK
- ------------- x 100 => par groupe de client
- Nb backup
-
- - Il faut ajouter une estimation des jobs qui auraient
- du se lancer (a voir avec les schedules)
-
- - Affichage en html/csv pour des stats
- grp, nb client, nb backup, nb ok, nb err, nb cancel,
- %ok, nb files, nb gig, time
-
- - Ajouter la liste des fichiers (quand il n'y en a pas trop)
- - Ajouter un mode qui compte le nombre de fichier sous bfileview
- x Ajouter une estimation de progression du backup basé sur le nombre
- de fichier et le nombre de Mo
- x Ajouter un bouton suivant/precedant dans la vue des logs
- x Ajouter la liste des medias qui vont/ont expirer et les pruner
- x Fixer les purge/prune de multiple volumes
- x Ajouter une gestion des utilisateurs avec des roles
- o Liste des roles possibles
- * view_stats
- * configure
- * run_job
- * run_restore
- * view_history
- * view_log
- * view_media
- * view_pool
- * update_media
- * view_autochanger
- * update_autochanger
- * cancel_job
-
- o Avoir des profiles ayant certains roles
- * admin (all)
- * customer (view_stats, view_history, view_log)
- * production (all - configure)
- ...
-
- o Pour faire la difference entre les groupes de la vue et
- les groupes d'acl, il faut ajouter un champs dans la table
- client_group (visible bool).
-
- o Ajout de 4 tables dans le catalogue
- - bweb_user (userid, username, passwd, comment) passwd with apache ?
- - bweb_role (roleid, rolename)
- - bweb_role_member (roleid, userid)
-
- - bweb_client_group_acl (client_group_id, userid)
- - bweb_pool_acl (poolid, userid)
-
- o Il faudrait aussi pouvoir choisir le login admin...
-
- x On specifie par user si on veut filter par les groupes (gestion un peu
- chiante, il faut ajouter les hosts dans les groupes, sinon, ils sont
- invisibles)
-
- x On recupere ce champs quand on check les can_do(); et apres, on le regarde
- avant d'envoyer le JOIN de filtre. (Attention, admin n'est pas soumis a ca)
-
- x On peut ajouter une option dans la Config pour activer ce mode ou pas.
-
- x Regarder la possibilite de recuperer toutes les roles au debut pour
- adapter les pages web... Il n'y a que les menus/actions autorises qui
- seraient affiches. (bp cancel => role cancel_job, configuration => role configure)
-
- * on utilise le commentaire depuis une page web, comme ca
- on gere la traduction sans toucher a la base
-
-CREATE TABLE bweb_user
-(
- userid serial not null,
- username text not null,
- use_acl boolean default false,
- comment text default '',
- passwd text default '',
- primary key (userid)
-);
-CREATE UNIQUE INDEX bweb_user_idx on bweb_user (username);
-
-CREATE TABLE bweb_role
-(
- roleid serial not null,
- rolename text not null,
--- comment text default '',
- primary key (roleid)
-);
-CREATE UNIQUE INDEX bweb_role_idx on bweb_role (rolename);
-
-INSERT INTO bweb_role (rolename) VALUES ('r_user_mgnt');
-INSERT INTO bweb_role (rolename) VALUES ('r_delete_job');
-INSERT INTO bweb_role (rolename) VALUES ('r_prune');
-INSERT INTO bweb_role (rolename) VALUES ('r_purge');
-INSERT INTO bweb_role (rolename) VALUES ('r_group_mgnt');
-INSERT INTO bweb_role (rolename) VALUES ('r_location_mgnt');
-INSERT INTO bweb_role (rolename) VALUES ('r_cancel_job');
-INSERT INTO bweb_role (rolename) VALUES ('r_run_job');
-INSERT INTO bweb_role (rolename) VALUES ('r_configure');
-INSERT INTO bweb_role (rolename) VALUES ('r_client_status');
-INSERT INTO bweb_role (rolename) VALUES ('r_view_job');
-
-CREATE TABLE bweb_role_member
-(
- roleid integer not null,
- userid integer not null,
- primary key (roleid, userid)
-);
-
-CREATE TABLE bweb_client_group_acl
-(
- client_group_id integer not null,
- userid integer not null,
- primary key (client_group_id, userid)
-);
-
- - Integrer brestore en mode javascript
- o ajouter une api
- .ls_dir(jobid,pathid)
- .ls_file(jobid,pathid)
- .get_pathid(jobid,"/")
- .genbsr (fileid, fileid, fileid, fileid, fileid...)
- -> on peut utiliser une table dans la base pour faire ca
- cf bat
-
-> 1. Unloading tapes assistent.
->
-> I'm using a script which selects tapes to unload. The idea is to
-> remove all volumes from the library that contain a current set of
-> backups. Basically, find the volumes from the most recent full backups
-> and all volumes that depend on these. Ignore older fulls and their
-> differentials and incrementals.
->
-> This is to ensure that, at the time volumes are unloaded, a complete
-> set of backups can be stored safely.
-
-Already ok
- Jobs -> Job Zoom -> View Media -> Select them -> Eject
-
-Yes, it's a very good idea, i see no difficulty to implement this kind of
-tool.
-
-Users go to
- Media -> Made a Safe backup set
- -> Select Client(s) -> Select Job(s) -> Backup set
-
-I think that i can do some sort of assistant to that.
-(with next, next next)
-
-
-> While volumes are prepared for unloading, I disable them, so Bacula
-> will not try to use them. Later, they are automatically re-enabled.
-
-x Do you use the Enabled flag for that ? It's a good idea.
-
-> Move these volumes (if possible) to the export slots.
-
-I have already some code for that, but at this time it doesn't use
-the mtx-script from bacula. (or bacula-sd commands)
-
-I have to change this, so user have a working mtx-scripts, and we use
-it everywhere. (The best solution is to send command to bacula-dir)
-
-> Later, request volumes to fill up the pools so there are usable
-> volumes for later backups around. Load these volumes from the import
-> slots to the regular working slots, and do an 'update slots'.
-
-I use the Scratch pool for this sort of things, but we could use an other
-assistant for that.
-
-Media -> I/O -> Fill pools -> Select pool(s) -> import selections
-
-bschedule:
- x Bug dans la determination des jours de la semaine (exemple de la full
- le premier dimanche du mois)
-
-manuel :
- - Avoir la version 2.0 et la version 2.2 en ligne (pour que les utilisateurs
- ne se trompent pas dans les versions)
- - Supprimer les (need bacula >= 1.xx) (dans la derniere version)
-
-bacula :
- - Faire un test de non regression avec pleins d'erreur
- o pb inclusion (distante, locale)
- o pb exclusion (distante, locale)
- o pb execution de commande
- o pb de config avec test du -t des differents daemon
- x Utiliser PQescapeStringConn a la place de PQescapeString
- - Utiliser la lib pcre
- - Rendre les scripts bacula-ctl-xxx LSB
- x Pouvoir utiliser les uid numeriques dans le backup des acl
- - Avoir un script qui dump la configuration pour faire
- des bug reports
- p modifier l'organisation de la table version (pour pouvoir ajouter
- les versions de bweb par exemple)
- - utiliser la meme fonction pour read_close_session et append_close_session
- x pb dans le message de chargement d'une bande pendant une resto
-
- Please mount Volume "R40175" or label a new one for
- Pas le bon message pour une resto (label a new one)
- - Impossible de lancer une restauration en meme temps qu'un backup sur
- un autochanger. Le code dans jobq.c qui controle les MaxConcurrentJobs
- ne prend pas en compte les autochanger avec plusieurs drives. Ce code
- fait surement doublon avec le nouveau code de reservation.
- Il faudrait le simplifier, et compter les jobs de restauration comme les
- jobs normaux. Le patch précédent ne changeait pas le MaxConcurrentJobs
- comme il faut à la fin du backup.
-
- x Accurate backup
- o Envoyer la liste de tous les fichiers au client dans un format simple
- /path/ LSTAT # un / a la fin pour un repertoire
- /path/file LSTAT
-
- o Le client construit un hash disque (ou en memoire ou les deux)
- o A chaque repertoire/fichier on verifie la presence du fichier dans le hash
- et on peut aussi comparer date/taille/bloc
- - Si le fichier n'est pas dedans, on le backup
- - Si le fichier est present on verifie les attributs et on mark le fichier comme vu
- o A la fin, on parcours tous le hash pour trouver les fichiers qui ne sont pas vu et
- on envoie la liste des fichiers supprimes avec le fileindex=0 et pourquoi pas la date
- du jour dans le champ mtime
- o Utiliser systematiquement l'option ignorecase sous windows
- p Ajouter une option pour avoir la table de stat
- Enable Statistic = yes/no
- Statistic retention = 4 years
- o use mmap to map hash ? (on 32b, we are limited to 1 or 2GB)
-
-#ifndef _WIN32
- ef->data = mmap(NULL, ef->data_size, PROT_READ,
- MAP_SHARED, fileno(ef->fp), 0);
-#else
- fm = CreateFileMapping((HANDLE) _get_osfhandle (fileno(ef->fp)),
- NULL,
- PAGE_READONLY,
- 0,
- 0,
- NULL);
- ef->data = MapViewOfFile(fm,
- FILE_MAP_READ,
- 0,
- 0,
- ef->data_size);
- CloseHandle(fm);
-#endif
-
- ef = eet_internal_read(ef);
- if (!ef)
-@@ -892,11 +862,7 @@
- free(ef->header);
- }
-
-#ifndef _WIN32
- if (ef->data) munmap((void*)ef->data, ef->data_size);
-#else
- if (ef->data) UnmapViewOfFile (ef->data);
-#endif
-
-if (ef->fp) fclose(ef->fp);
-
- - Accurate backup (kern)
-1. Run bconsole
-2. Dir -> FD run job
-*3. FD does a normal backup and at the same time makes a list of all files on
-the system (in the FileSet), marking which ones were just now backed up.
-4. For each file backed up send attributes/data to SD. Note, this is done
-during step 3 above. Minor difference, the connection with the SD is not
-dropped at the end of the backup -- see later.
-*5. Send the list of all files including those backed up to the Dir
- --> Send to SD and DIR at the same time ?
- filed/backup.c/encode_and_send_attributes
-
-6. Dir computes files and deleted files.
-7. Dir sends list of additional files (new files) to backup, and list of files
-deleted.
-8. FD does backup of files Dir says to save.
-9. FD sends SD attrs of backed up files
-10. FD sends SD delete records for files Dir wants deleted.
-*11. FD connection to SD can be closed, this part of the backup is done.
-*12. FD sends new list of files just backed up to Dir
-*13. Dir adds newly backed up files to previous list sent by FD
-*14. Dir "batch" inserts complete new list in the catalog (I forgot the name
-of the new table). Note this table has nothing to do with the File table.
-*15. Dir deletes previous list in catalog.
-*16. Dir does normal batch insert of attributes from SD, but must handle
-deleted records. Note, this will probably happen at the same time as the
-items 13-15.
-
-
-
- - TODO:
- 0001088: volume FirstWritten attribute is set to time of mount request, not time of first write
- Description When a Bacula job requests mounting a tape volume that is not present in the drive,
- once the tape is mounted, its FirstWritten attribute is set to the time when the volume was requested.
- Consequently, if the job has been waiting longer than the maximum use duration of the volume,
- the volume is promoted to Used immediately because the maximum use duration has apparently expired before
- the use has even started.
-
-To avoid that, the FirstWritten attribute should be set to the time the volume was mounted (= the current time when the setting takes place).
-
- x Backup a file that is not in accurate list (change NOCHG to LINK, FILE, etc..)
- * Manage JobFiles (Deleted compte pour 1 ?)
-
- x Utiliser le check_accurate dans find_one et declencher le save_file
- si besoin en desactivant le incremental.
- x ne va pas marcher avec le strip path (la recherche est faite avant le strip path)
- * on peut utiliser le champs LStat de la base pour noter que le fichier est supprimé...
-
- CREATE TEMPORARY TABLE btemp2 AS (
- SELECT max(FileId) as FileId, PathId, FilenameId
- FROM (SELECT FileId, PathId, FilenameId FROM File WHERE JobId IN (39867,40341)) AS F
- GROUP BY PathId, FilenameId )
-
- SELECT Path.Path, Filename.Name, File.FileIndex, File.JobId, File.LStat
- FROM (
- SELECT max(FileId) as FileId, PathId, FilenameId
- FROM (SELECT FileId, PathId, FilenameId FROM File WHERE JobId IN (11,13)) AS F
- GROUP BY PathId, FilenameId
- ) AS Temp
- JOIN Filename ON (Filename.FilenameId = Temp.FilenameId)
- JOIN Path ON (Path.PathId = Temp.PathId)
- JOIN File ON (File.FileId = Temp.FileId)
- WHERE FileIndex > 0
-
-
- SELECT File.FileIndex, Path.Path, Filename.Name, File.LStat
- FROM btemp2 JOIN Path USING (PathId) JOIN Filename USING (FilenameId)
- JOIN File USING (FileId)
- WHERE File.FileIndex > 0
-
- DROP TABLE btemp2
-*/
-/*
-SELECT DISTINCT ON (PathId, FilenameId) FileIndex, Path, Name, LStat
- FROM File JOIN Filename USING (FilenameId) JOIN Path USING (PathId) WHERE JobId IN (40341)
- ORDER BY PathId, FilenameId, JobId DESC
-*/
-
- - .api mode:
-Some ideas :
-- Every dates have to be in ISO format
-YYYY-MM-DD HH:MM:SS
-- JobLevel, JobStatus, etc.. have to use C constant T,R,a,A,f...
-- Sizes are always in bytes (no suffix)
-- Numbers have to be used without commas
-- If we change (add) something, we must always add new elements
-at the end.
-
-For director status on running jobs, it will be great to display :
-JobId, Client name, Job Name, Level, Start Time and Status
-
-
- x Utiliser une alist dans les runscripts
-
-RunScript {
- console = "xxxx"
- console = "yyy"
- console = "zzzz"
-}
-
-or possibly
-
-RunScript {
- console = "xxxx", "yyyy", "zzzz"
- console = "aaaa"
-}
-
- o cleanup bextract to use filed code
-
+++ /dev/null
-Index: match_bsr.c
-===================================================================
---- match_bsr.c (révision 8116)
-+++ match_bsr.c (copie de travail)
-@@ -36,15 +36,6 @@
-
- /*
- * ***FIXME***
-- * find_smallest_volfile needs to be fixed to only look at items that
-- * are not marked as done. Otherwise, it can find a bsr
-- * that has already been consumed, and this will cause the
-- * bsr to be used, thus we may seek back and re-read the
-- * same records, causing an error. This deficiency must
-- * be fixed. For the moment, it has been kludged in
-- * read_record.c to avoid seeking back if find_next_bsr
-- * returns a bsr pointing to a smaller address (file/block).
-- *
- * Also for efficiency, once a bsr is done, it really should be
- * delinked from the bsr chain. This will avoid the above
- * problem and make traversal of the bsr chain more efficient.
-@@ -255,68 +246,88 @@
- }
-
- /*
-- * ***FIXME***
-- * This routine needs to be fixed to only look at items that
-- * are not marked as done. Otherwise, it can find a bsr
-- * that has already been consumed, and this will cause the
-- * bsr to be used, thus we may seek back and re-read the
-- * same records, causing an error. This deficiency must
-- * be fixed. For the moment, it has been kludged in
-- * read_record.c to avoid seeking back if find_next_bsr
-- * returns a bsr pointing to a smaller address (file/block).
-+ * Get the smallest file number from this volfile part
-+ * Don't use "done" elements
- */
--static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr)
-+static bool get_smallest_volfile(BSR_VOLFILE *vf, uint32_t *ret)
- {
-- BSR *return_bsr = found_bsr;
-- BSR_VOLFILE *vf;
-- BSR_VOLBLOCK *vb;
-- uint32_t found_bsr_sfile, bsr_sfile;
-- uint32_t found_bsr_sblock, bsr_sblock;
-+ bool ok=false;
-+ uint32_t min_val=0;
-
-- /* Find the smallest file in the found_bsr */
-- vf = found_bsr->volfile;
-- found_bsr_sfile = vf->sfile;
-- while ( (vf=vf->next) ) {
-- if (vf->sfile < found_bsr_sfile) {
-- found_bsr_sfile = vf->sfile;
-+ for (; vf ; vf = vf->next) {
-+ if (!vf->done) {
-+ if (ok) {
-+ min_val = MIN(min_val, vf->sfile);
-+ } else {
-+ min_val = vf->sfile;
-+ ok=true;
-+ }
- }
- }
-+ *ret = min_val;
-+ return ok;
-+}
-
-- /* Find the smallest file in the bsr */
-- vf = bsr->volfile;
-- bsr_sfile = vf->sfile;
-- while ( (vf=vf->next) ) {
-- if (vf->sfile < bsr_sfile) {
-- bsr_sfile = vf->sfile;
-+/*
-+ * Get the smallest block number from this volblock part
-+ * Don't use "done" elements
-+ */
-+static bool get_smallest_volblock(BSR_VOLBLOCK *vb, uint32_t *ret)
-+{
-+ bool ok=false;
-+ uint32_t min_val=0;
-+
-+ for (; vb ; vb = vb->next) {
-+ if (!vb->done) {
-+ if (ok) {
-+ min_val = MIN(min_val, vb->sblock);
-+ } else {
-+ min_val = vb->sblock;
-+ ok=true;
-+ }
- }
- }
-+ *ret = min_val;
-+ return ok;
-+}
-+
-+/*
-+ *
-+ */
-+static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr)
-+{
-+ BSR *return_bsr = found_bsr;
-+ uint32_t found_bsr_sfile=0, bsr_sfile=0;
-+ uint32_t found_bsr_sblock=0, bsr_sblock=0;
-+
-+ if (!get_smallest_volfile(found_bsr->volfile, &found_bsr_sfile)) {
-+ return bsr; /* found_bsr seems to be done...*/
-+ }
-+
-+ if (!get_smallest_volfile(bsr->volfile, &bsr_sfile)) {
-+ return found_bsr; /* bsr seems to be done... */
-+ }
-
- /* if the bsr file is less than the found_bsr file, return bsr */
- if (found_bsr_sfile > bsr_sfile) {
- return_bsr = bsr;
- } else if (found_bsr_sfile == bsr_sfile) {
-- /* Files are equal */
-- /* find smallest block in found_bsr */
-- vb = found_bsr->volblock;
-- found_bsr_sblock = vb->sblock;
-- while ( (vb=vb->next) ) {
-- if (vb->sblock < found_bsr_sblock) {
-- found_bsr_sblock = vb->sblock;
-- }
-+ /* Files are equal, use block to find the smallest */
-+ if (!get_smallest_volblock(found_bsr->volblock, &found_bsr_sblock)) {
-+ return bsr; /* Should not be there */
- }
-- /* Find smallest block in bsr */
-- vb = bsr->volblock;
-- bsr_sblock = vb->sblock;
-- while ( (vb=vb->next) ) {
-- if (vb->sblock < bsr_sblock) {
-- bsr_sblock = vb->sblock;
-- }
-+
-+ if (!get_smallest_volblock(bsr->volblock, &bsr_sblock)) {
-+ return found_bsr; /* Should not be there */
- }
-+
- /* Compare and return the smallest */
- if (found_bsr_sblock > bsr_sblock) {
- return_bsr = bsr;
- }
- }
-+ Dmsg5(dbglevel, "find_smallest_volfile bsr=0x%p %i > %i | %i > %i\n",
-+ return_bsr, found_bsr_sfile, bsr_sfile, found_bsr_sblock, bsr_sblock);
- return return_bsr;
- }
-
-@@ -360,9 +371,9 @@
- static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
- SESSION_LABEL *sessrec, bool done, JCR *jcr)
- {
-- Dmsg0(050, "Enter match_all\n");
-+ Dmsg1(050, "Enter match_all bsr=0x%p\n", bsr);
- if (bsr->done) {
--// Dmsg0(dbglevel, "bsr->done set\n");
-+ Dmsg1(dbglevel, "bsr->done set bsr=0x%p\n", bsr);
- goto no_match;
- }
- if (!match_volume(bsr, bsr->volume, volrec, 1)) {
-@@ -386,8 +397,6 @@
- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
- goto no_match;
- }
-- Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n",
-- rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
-
- if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) {
- Dmsg2(dbglevel, "Fail on sesstime. bsr=%u rec=%u\n",
-@@ -411,6 +420,9 @@
- Dmsg3(dbglevel, "match on findex=%d. bsr=%d,%d\n",
- rec->FileIndex, bsr->FileIndex->findex, bsr->FileIndex->findex2);
-
-+ Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n",
-+ rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
-+
- if (!match_fileregex(bsr, rec, jcr)) {
- Dmsg1(dbglevel, "Fail on fileregex='%s'\n", bsr->fileregex);
- goto no_match;
-@@ -607,14 +619,7 @@
-
- static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done)
- {
-- /*
-- * Currently block matching does not work correctly for disk
-- * files in all cases, so it is "turned off" by the following
-- * return statement.
-- */
-- return 1;
-
--
- if (!volblock) {
- return 1; /* no specification matches all */
- }
-@@ -622,9 +627,19 @@
- if (rec->state & REC_ISTAPE) {
- return 1; /* All File records OK for this match */
- }
--// Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
--// volblock->sblock, volblock->eblock, rec->Block);
-- if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
-+ Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
-+ volblock->sblock, volblock->eblock, rec->Block);
-+
-+ /* FIXME */
-+ /* Don't reject the call if we are called with a small offset */
-+ uint32_t min = (volblock->sblock>DEFAULT_BLOCK_SIZE)?volblock->sblock-DEFAULT_BLOCK_SIZE:0;
-+
-+ /* We have call where rec->Block is the block after EndBlock
-+ * But, we are already decoding rec->Block-1Block records
-+ */
-+ uint32_t max = volblock->eblock+DEFAULT_BLOCK_SIZE;
-+// if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
-+ if (min <= rec->Block && max >= rec->Block) {
- return 1;
- }
- /* Once we get past last eblock, we are done */
-Index: read_record.c
-===================================================================
---- read_record.c (révision 8116)
-+++ read_record.c (copie de travail)
-@@ -261,8 +261,8 @@
- Dmsg2(100, "All done=(file:block) %u:%u\n", dev->file, dev->block_num);
- break;
- } else if (rec->match_stat == 0) { /* no match */
-- Dmsg4(100, "BSR no match: clear rem=%d FI=%d before set_eof pos %u:%u\n",
-- rec->remainder, rec->FileIndex, dev->file, dev->block_num);
-+ Dmsg7(100, "BSR no match: clear rem=%d FI=%d rec->Block=%d dev->LastBlock=%d dev->EndBlock=%d before set_eof pos %u:%u\n",
-+ rec->remainder, rec->FileIndex, rec->Block, dev->LastBlock, dev->EndBlock, dev->file, dev->block_num);
- rec->remainder = 0;
- rec->state &= ~REC_PARTIAL_RECORD;
- if (try_repositioning(jcr, rec, dcr)) {
-@@ -346,6 +346,9 @@
- */
- if (dev->file > bsr->volfile->sfile ||
- (dev->file == bsr->volfile->sfile && dev->block_num > bsr->volblock->sblock)) {
-+ Dmsg4(dbglvl, _("Reposition from (file:block) %u:%u to %u:%u\n"),
-+ dev->file, dev->block_num, bsr->volfile->sfile,
-+ bsr->volblock->sblock);
- return false;
- }
- if (verbose) {
-Index: parse_bsr.c
-===================================================================
---- parse_bsr.c (révision 8116)
-+++ parse_bsr.c (copie de travail)
-@@ -190,6 +190,9 @@
- for (bsr=root_bsr; bsr; bsr=bsr->next) {
- bsr->root = root_bsr;
- }
-+ if (verbose) {
-+ dump_bsr(root_bsr, true);
-+ }
- return root_bsr;
- }
-
-Index: bls.c
-===================================================================
---- bls.c (révision 8116)
-+++ bls.c (copie de travail)
-@@ -400,8 +400,8 @@
-
- if (file_is_included(ff, attr->fname) && !file_is_excluded(ff, attr->fname)) {
- if (verbose) {
-- Pmsg5(-1, _("FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d\n"),
-- rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
-+ Pmsg6(-1, _("FileIndex=%d VolSessionId=%d VolSessionTime=%d Stream=%d DataLen=%d Block=%x\n"),
-+ rec->FileIndex, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len, rec->Block);
- }
- print_ls_output(jcr, attr);
- num_files++;
-Index: bscan.c
-===================================================================
---- bscan.c (révision 8146)
-+++ bscan.c (copie de travail)
-@@ -420,9 +420,9 @@
- }
-
- if (list_records) {
-- Pmsg5(000, _("Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u\n"),
-+ Pmsg6(000, _("Record: SessId=%u SessTim=%u FileIndex=%d Stream=%d len=%u block=%u\n"),
- rec->VolSessionId, rec->VolSessionTime, rec->FileIndex,
-- rec->Stream, rec->data_len);
-+ rec->Stream, rec->data_len, rec->Block);
- }
- /*
- * Check for Start or End of Session Record
+++ /dev/null
- This patch fixes a bootstrap creation file problem when
- all daemons have the same name. It fixes bug #1233.
-
- Apply it to trunk with:
-
- cd <bacula-source>
- patch -p0 < fix_1233_bootstrap_name.patch
- ./configure <your options>
- make
- ...
- make install
-
-
-
-Index: src/filed/job.c
-===================================================================
---- src/filed/job.c (révision 8483)
-+++ src/filed/job.c (copie de travail)
-@@ -1190,7 +1190,7 @@
- free_bootstrap(jcr);
- P(bsr_mutex);
- bsr_uniq++;
-- Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
-+ Mmsg(fname, "%s/%s.%s.%d.fd.bootstrap", me->working_directory, me->hdr.name,
- jcr->Job, bsr_uniq);
- V(bsr_mutex);
- Dmsg1(400, "bootstrap=%s\n", fname);
-Index: src/stored/fd_cmds.c
-===================================================================
---- src/stored/fd_cmds.c (révision 8483)
-+++ src/stored/fd_cmds.c (copie de travail)
-@@ -344,7 +344,7 @@
- }
- P(bsr_mutex);
- bsr_uniq++;
-- Mmsg(fname, "%s/%s.%s.%d.bootstrap", me->working_directory, me->hdr.name,
-+ Mmsg(fname, "%s/%s.%s.%d.sd.bootstrap", me->working_directory, me->hdr.name,
- jcr->Job, bsr_uniq);
- V(bsr_mutex);
- Dmsg1(400, "bootstrap=%s\n", fname);
+++ /dev/null
-Index: src/dird/job.c
-===================================================================
---- src/dird/job.c (révision 8005)
-+++ src/dird/job.c (copie de travail)
-@@ -545,13 +545,20 @@
- {
- bool cancel = false;
- JOB *job = jcr->job;
-+ utime_t current=0;
-
- if (!job_waiting(jcr)) {
- return false;
- }
-- Dmsg3(200, "check maxwaittime %u - %u >= %u\n", watchdog_time, jcr->wait_time, job->MaxWaitTime);
-+
-+ if (jcr->wait_time) {
-+ current = watchdog_time - jcr->wait_time;
-+ }
-+
-+ Dmsg3(200, "check maxwaittime %u >= %u\n",
-+ current + jcr->wait_time_sum, job->MaxWaitTime);
- if (job->MaxWaitTime != 0 &&
-- (watchdog_time - jcr->wait_time) >= job->MaxWaitTime) {
-+ (current + jcr->wait_time_sum) >= job->MaxWaitTime) {
- cancel = true;
- }
-
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (révision 8005)
-+++ src/jcr.h (copie de travail)
-@@ -216,7 +216,8 @@
- time_t start_time; /* when job actually started */
- time_t run_time; /* used for computing speed */
- time_t end_time; /* job end time */
-- time_t wait_time; /* when job have started to wait */
-+ time_t wait_time_sum; /* cumulative wait time since job start */
-+ time_t wait_time; /* timestamp when job have started to wait */
- POOLMEM *client_name; /* client name */
- POOLMEM *RestoreBootstrap; /* Bootstrap file to restore */
- POOLMEM *stime; /* start time for incremental/differential */
-Index: src/lib/jcr.c
-===================================================================
---- src/lib/jcr.c (révision 8005)
-+++ src/lib/jcr.c (copie de travail)
-@@ -738,41 +738,29 @@
- return priority;
- }
-
--void set_jcr_job_status(JCR *jcr, int JobStatus)
-+
-+static void update_wait_time(JCR *jcr, int newJobStatus)
- {
-- bool set_waittime = false;
-- int oldJobStatus = jcr->JobStatus;
-- int priority, old_priority;
-+ bool enter_in_waittime;
-+ int oldJobStatus = jcr->JobStatus;
-
-- priority = get_status_priority(JobStatus);
-- old_priority = get_status_priority(oldJobStatus);
--
-- Dmsg2(800, "set_jcr_job_status(%s, %c)\n", jcr->Job, JobStatus);
-- /* if wait state is new, we keep current time for watchdog MaxWaitTime */
-- switch (JobStatus) {
-- case JS_WaitFD:
-- case JS_WaitSD:
-- case JS_WaitMedia:
-- case JS_WaitMount:
-- case JS_WaitStoreRes:
-- case JS_WaitJobRes:
-- case JS_WaitClientRes:
-- case JS_WaitMaxJobs:
-- case JS_WaitPriority:
-- set_waittime = true;
-- default:
-- break;
-- }
--
-- /*
-- * For a set of errors, ... keep the current status
-- * so it isn't lost. For all others, set it.
-- */
-- Dmsg3(300, "jid=%u OnEntry JobStatus=%c set=%c\n", (uint32_t)jcr->JobId,
-- jcr->JobStatus, JobStatus);
-- if (priority >= old_priority) {
-- jcr->JobStatus = JobStatus; /* replace with new priority */
-+ switch (newJobStatus) {
-+ case JS_WaitFD:
-+ case JS_WaitSD:
-+ case JS_WaitMedia:
-+ case JS_WaitMount:
-+ case JS_WaitStoreRes:
-+ case JS_WaitJobRes:
-+ case JS_WaitClientRes:
-+ case JS_WaitMaxJobs:
-+ case JS_WaitPriority:
-+ enter_in_waittime = true;
-+ break;
-+ default:
-+ enter_in_waittime = false; /* not a Wait situation */
-+ break;
- }
-+
- /*
- * If we were previously waiting and are not any more
- * we want to update the wait_time variable, which is
-@@ -788,13 +776,43 @@
- case JS_WaitClientRes:
- case JS_WaitMaxJobs:
- case JS_WaitPriority:
-- set_waittime = false; /* keep old time */
-+ if (!enter_in_waittime) { /* we get out the wait time */
-+ jcr->wait_time_sum += (time(NULL) - jcr->wait_time);
-+ jcr->wait_time = 0;
-+ }
-+ break;
-+
-+ /* if wait state is new, we keep current time for watchdog MaxWaitTime */
- default:
-- if (set_waittime) {
-- Dmsg0(800, "Setting wait_time\n");
-+ if (enter_in_waittime) {
- jcr->wait_time = time(NULL);
- }
-+ break;
- }
-+}
-+
-+void set_jcr_job_status(JCR *jcr, int JobStatus)
-+{
-+ int priority, old_priority;
-+ int oldJobStatus = jcr->JobStatus;
-+ priority = get_status_priority(JobStatus);
-+ old_priority = get_status_priority(oldJobStatus);
-+
-+ Dmsg2(800, "set_jcr_job_status(%s, %c)\n", jcr->Job, JobStatus);
-+
-+ /* Update wait_time depending on newJobStatus and oldJobStatus */
-+ update_wait_time(jcr, JobStatus);
-+
-+ /*
-+ * For a set of errors, ... keep the current status
-+ * so it isn't lost. For all others, set it.
-+ */
-+ Dmsg3(300, "jid=%u OnEntry JobStatus=%c set=%c\n", (uint32_t)jcr->JobId,
-+ jcr->JobStatus, JobStatus);
-+ if (priority >= old_priority) {
-+ jcr->JobStatus = JobStatus; /* replace with new priority */
-+ }
-+
- if (oldJobStatus != jcr->JobStatus) {
- Dmsg3(200, "jid=%u leave set_old_job_status=%c new_set=%c\n", (uint32_t)jcr->JobId,
- oldJobStatus, JobStatus);
+++ /dev/null
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <time.h>
-
-int64_t get_current_time()
-{
- struct timeval tv;
- if (gettimeofday(&tv, NULL) != 0) {
- tv.tv_sec = (long)time(NULL); /* fall back to old method */
- tv.tv_usec = 0;
- }
- return (int64_t)tv.tv_sec * 1000000 + (int64_t)tv.tv_usec;
-}
-
-#ifdef USE_TCHDB
-# include <tcutil.h>
-# include <tchdb.h>
-
-TCHDB *hdb;
-TCXSTR *kstr;
-TCXSTR *dstr;
-
-bool hash_init(int nbelt)
-{
- int opt=HDBTLARGE ;//| HDBTTCBS;
-
- /* create the object */
- hdb = tchdbnew();
-
- kstr = tcxstrnew();
- dstr = tcxstrnew();
-
- tchdbsetcache(hdb, nbelt);
- fprintf(stderr, "cache;%i\n", nbelt);
- tchdbtune(hdb, nbelt*4, -1, 16, 0);
-
- fprintf(stderr, "bucket;%lli\n", (int64_t) nbelt*4);
- fprintf(stderr, "option;%i\n", opt);
- unlink("casket.hdb");
-
- /* open the database */
- if(!tchdbopen(hdb, "casket.hdb", HDBOWRITER | HDBOCREAT)){
- fprintf(stderr, "open error\n");
- exit (1);
- }
- return 1;
-}
-
-bool hash_put(char *key, char *val)
-{
- int ecode;
-
- if (!tchdbputasync2(hdb, key, val)) {
- ecode = tchdbecode(hdb);
- fprintf(stderr, "put error: %s\n", tchdberrmsg(ecode));
- return 0;
- }
- return 1;
-}
-
-char *hash_get(char *key, char *ret, int len)
-{
- return tchdbget2(hdb, key);
-}
-
-void hash_free(char *ret)
-{
- free(ret);
-}
-
-void cleanup()
-{
- tchdbclose(hdb);
- tchdbdel(hdb);
-}
-
-void hash_iterinit()
-{
- /* traverse records */
- tchdbiterinit(hdb);
-}
-
-bool hash_next(char *line, int len1, char *data, int len2)
-{
- return tchdbiternext3(hdb, kstr, dstr);
-}
-
-void hash_iterdone()
-{
-}
-
-#endif
-
-
-#ifdef USE_TCBDB
-# include <tcutil.h>
-# include <tcbdb.h>
-
-TCBDB *hdb;
-TCXSTR *kstr;
-TCXSTR *dstr;
-
-bool hash_init(int nbelt)
-{
- int opt=HDBTLARGE ;//| HDBTTCBS;
-
- /* create the object */
- hdb = tcbdbnew();
-
- kstr = tcxstrnew();
- dstr = tcxstrnew();
-
- fprintf(stderr, "cache;%i\n", -1);
- tcbdbtune(hdb, 0, 0, nbelt*4, -1, -1, opt);
-
- fprintf(stderr, "bucket;%lli\n", (int64_t) nbelt*4);
- fprintf(stderr, "option;%i\n", opt);
- unlink("casket.hdb");
-
- /* open the database */
- if(!tcbdbopen(hdb, "casket.hdb", HDBOWRITER | HDBOCREAT)){
- fprintf(stderr, "open error\n");
- exit (1);
- }
- return 1;
-}
-
-bool hash_put(char *key, char *val)
-{
- int ecode;
-
- if (!tcbdbput(hdb, key, strlen(key), val, strlen(val)+1)) {
- ecode = tcbdbecode(hdb);
- fprintf(stderr, "put error: %s\n", tcbdberrmsg(ecode));
- return 0;
- }
- return 1;
-}
-
-char *hash_get(char *key, char *ret, int len)
-{
- return tcbdbget2(hdb, key);
-}
-
-void hash_free(char *ret)
-{
- free(ret);
-}
-
-void cleanup()
-{
- tcbdbclose(hdb);
- tcbdbdel(hdb);
-}
-BDBCUR *iter;
-void hash_iterinit()
-{
- /* traverse records */
- iter = tcbdbcurnew(hdb);
- tcbdbcurfirst(iter);
-}
-
-bool hash_next(char *line, int len1, char *data, int len2)
-{
- bool ret = tcbdbcurrec(iter, kstr, dstr);
- tcbdbcurnext(iter);
- return ret;
-}
-
-void hash_iterdone()
-{
- tcbdbcurdel(iter);
-}
-
-#endif
-
-
-#ifdef USE_DB
-# include <db.h>
-DBT dbkey, dbdata;
-DB *hdb;
-bool hash_init(int nbelt)
-{
- int ret;
-
- /* Create and initialize database object, open the database. */
- if ((ret = db_create(&hdb, NULL, 0)) != 0) {
- fprintf(stderr,
- "db_create: %s\n", db_strerror(ret));
- exit (1);
- }
- hdb->set_errfile(hdb, stderr);
- hdb->set_errpfx(hdb, "hash");
- if ((ret = hdb->set_pagesize(hdb, 1024)) != 0) {
- hdb->err(hdb, ret, "set_pagesize");
- exit (1);
- }
- if ((ret = hdb->set_cachesize(hdb, 0, 32 * 1024 * 1024, 0)) != 0) {
- hdb->err(hdb, ret, "set_cachesize");
- exit (1);;
- }
- fprintf(stderr, "cache;%lli\n", (int64_t)32 * 1024 * 1024);
- fprintf(stderr, "bucket;0\n");
- fprintf(stderr, "option;0\n");
-
- remove("access.db");
- if ((ret = hdb->open(hdb,
- NULL, "access.db", NULL, DB_BTREE, DB_CREATE, 0664)) != 0) {
- hdb->err(hdb, ret, "access.db: open");
- exit (1);
- }
- memset(&dbkey, 0, sizeof(DBT));
- memset(&dbdata, 0, sizeof(DBT));
-
- return 1;
-}
-
-bool hash_put(char *key, char *val)
-{
- int ret;
- dbkey.data = key;
- dbkey.size = (u_int32_t)strlen(key);
- dbdata.data = val;
- dbdata.size = strlen(val)+1;
- if ((ret = hdb->put(hdb, NULL, &dbkey, &dbdata, 0))) {
- hdb->err(hdb, ret, "DBcursor->put");
- return 0;
- }
- return 1;
-}
-
-void cleanup()
-{
- hdb->close(hdb, 0);
-}
-
-char *hash_get(char *key, char *ret, int len)
-{
-/* Zero out the DBTs before using them. */
- memset(&dbkey, 0, sizeof(DBT));
- memset(&dbdata, 0, sizeof(DBT));
-
- dbkey.data = key;
- dbkey.ulen = strlen(key);
-
- dbdata.data = ret;
- dbdata.ulen = len;
- dbdata.flags = DB_DBT_USERMEM;
-
- if (hdb->get(hdb, NULL, &dbkey, &dbdata, 0) == 0) {
- return (char *)dbdata.data;
- } else {
- return NULL;
- }
-}
-
-void hash_free(char *ret)
-{
-}
-
-DBC *cursorp=NULL;
-void hash_iterinit()
-{
- hdb->cursor(hdb, NULL, &cursorp, 0);
-}
-
-bool hash_next(char *line, int len1, char *data, int len2)
-{
- return cursorp->c_get(cursorp, &dbkey, &dbdata, DB_NEXT) == 0;
-}
-
-void hash_iterdone()
-{
- if (cursorp != NULL)
- cursorp->c_close(cursorp);
-}
-
-
-#endif
-
-
-
-int main(int argc, char **argv)
-{
- char *start_heap = (char *)sbrk(0);
-
- char *value;
- int i=0;
- char save_key[200];
- char mkey[200];
- char data[200];
- int64_t ctime, ttime;
-
- if (argc != 4) {
- fprintf(stderr, "Usage: tt count file cache\n");
- exit(1);
- }
-
- hash_init(atoll(argv[1]));
-
- FILE *fp = fopen(argv[2], "r");
- if (!fp) {
- fprintf(stderr, "open %s file error\n", argv[2]);
- exit (1);
- }
- char line[2048];
- sprintf(data, "AOOODS SDOOQSD A BBBBB AAAAA ZEZEZQS SQDSQDQ DSQ DAZEA ZEA S");
-
- ctime = get_current_time();
- fprintf(stderr, "elt;time\n");
- while (fgets(line, sizeof(line), fp)) {
- i++;
-
- hash_put(line, data);
-
- if (i == 99) {
- strcpy(save_key, mkey);
- }
-
- if (i%100000 == 0) {
- ttime= get_current_time();
- fprintf(stderr, "%i;%i\n",
- i/100000, (int) ((ttime - ctime)/1000));
- }
- }
- ttime= get_current_time();
- fclose(fp);
-
- printf("loading %i file into hash database in %ims\n",
- i, (ttime - ctime)/1000);
-
- fprintf(stderr, "load;%i\n", (ttime - ctime)/1000);
- fprintf(stderr, "elt;%i\n", i);
-
- ////////////////////////////////////////////////////////////////
-
- fp = fopen(argv[2], "r");
- if (!fp) {
- fprintf(stderr, "open %s file error\n", argv[2]);
- exit (1);
- }
- i=0;
- ctime = get_current_time();
- char *p;
- fprintf(stderr, "elt;time\n");
- while (fgets(line, sizeof(line), fp)) {
- i++;
- p = hash_get(line, data, sizeof(data));
- if (p) {
- p[5]='H';
- hash_put(line, p);
- }
-
- if (i%100000 == 0) {
- ttime= get_current_time();
- fprintf(stderr, "%i;%i\n",
- i/100000, (int) ((ttime - ctime)/1000));
- }
-
- hash_free(p);
- }
- ttime= get_current_time();
- fprintf(stderr, "seen;%i\n", (ttime - ctime)/1000);
-
- fprintf(stderr, "elt;time\n");
- i=0;
- hash_iterinit();
- while(hash_next(line, sizeof(line), data, sizeof(data)))
- {
- i++;
- if (i%100000 == 0) {
- ttime= get_current_time();
- fprintf(stderr, "%i;%i\n",
- i/100000, (int) ((ttime - ctime)/1000));
- }
- }
- hash_iterdone();
-
- ttime = get_current_time();
- fprintf(stderr, "walk;%i\n", (ttime - ctime)/1000);
-
- fprintf(stderr, "heap;%lld\n", (long long)((char *)sbrk(0) - start_heap));
-
- cleanup();
-
- return 0;
-}
+++ /dev/null
-
-This patch improve a bit performance during attribute despooling
-
-
-Index: src/dird/getmsg.c
-===================================================================
---- src/dird/getmsg.c (révision 8258)
-+++ src/dird/getmsg.c (copie de travail)
-@@ -198,6 +198,11 @@
- continue;
- }
-
-+ if (bs->msg[0] == 'U') { /* SD sending attributes */
-+ Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
-+ catalog_update(jcr, bs);
-+ continue;
-+ }
- /*
- * Here we are expecting a message of the following format:
- * Jmsg Job=nnn type=nnn level=nnn Message-string
-@@ -231,11 +236,6 @@
- catalog_request(jcr, bs);
- continue;
- }
-- if (bs->msg[0] == 'U') { /* SD sending attributes */
-- Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
-- catalog_update(jcr, bs);
-- continue;
-- }
- if (bs->msg[0] == 'M') { /* Mount request */
- Dmsg1(900, "Mount req: %s", bs->msg);
- mount_request(jcr, bs, msg);
+++ /dev/null
-/*
- * This file is used to test simple I/O operation for accurate mode
- *
- *
- * 1) Loading
- * fseek() ?
- * fwrite()
- *
- * 2) Fetch + Update
- * fseek(pos1)
- * fread()
- * fseek(pos1)
- * fwrite()
- *
- * 3) Read all
- * fseek()
- * fread()
- *
- */
-
-/*
- cd regress/build
- make
- cd patches/testing
- g++ -g -Wall -I../../src -I../../src/lib -L../../src/lib justdisk.c -lbac -lpthread -lssl -D_TEST_TREE
- find / > lst
- ./a.out
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include "bacula.h"
-#include "dird/dird.h"
-typedef struct {
- char *path;
- char *fname;
- int32_t seen;
- int32_t pad;
- int64_t mtime;
- int64_t ctime;
-} AccurateElt;
-
-#define NB_ELT 500
-
-typedef struct {
- char *buf;
- rblink link;
-} MY;
-
-typedef struct {
- char *path;
- char *fname;
- int64_t index;
- rblink link;
-} MY_INDEX;
-
-static int my_index_cmp(void *item1, void *item2)
-{
- MY_INDEX *elt1, *elt2;
- elt1 = (MY_INDEX *) item1;
- elt2 = (MY_INDEX *) item2;
- int r = strcmp(elt1->fname, elt2->fname);
- if (r) {
- return r;
- }
- r = strcmp(elt1->path, elt2->path);
- return r;
-}
-
-static int my_cmp(void *item1, void *item2)
-{
- MY *elt1, *elt2;
- elt1 = (MY *) item1;
- elt2 = (MY *) item2;
- return strcmp(elt1->buf, elt2->buf);
-}
-
-rblist *load_rb(const char *file)
-{
- FILE *fp;
- char buffer[1024];
- MY *res;
- rblist *lst;
- lst = New(rblist(res, &res->link));
-
- fp = fopen(file, "r");
- if (!fp) {
- return NULL;
- }
- while (fgets(buffer, sizeof(buffer), fp)) {
- if (*buffer) {
- int len = strlen(buffer);
- if (len > 0) {
- buffer[len-1]=0; /* zap \n */
- }
- MY *buf = (MY *)malloc(sizeof(MY));
- memset(buf, 0, sizeof(MY));
- buf->buf = bstrdup(buffer);
- res = (MY *)lst->insert(buf, my_cmp);
- if (res != buf) {
- free(buf->buf);
- free(buf);
- }
- }
- }
- fclose(fp);
-
- return lst;
-}
-
-/* buffer used for 4k io operations */
-class AccurateBuffer
-{
-public:
- AccurateBuffer() {
- _fp=NULL;
- _nb=-1;
- _max_nb=-1;
- _dirty=0;
- memset(_buf, 0, sizeof(_buf));
- };
- void *get_elt(int nb);
- void init();
- void destroy();
- void update_elt(int nb);
- ~AccurateBuffer() {
- destroy();
- }
-private:
- char _buf[4096];
- int _nb;
- int _max_nb;
- char _dirty;
- FILE *_fp;
-};
-
-void AccurateBuffer::init()
-{
- _fp = fopen("testfile", "w+");
- if (!_fp) {
- exit(1);
- }
- _nb=-1;
- _max_nb=-1;
-}
-
-void AccurateBuffer::destroy()
-{
- if (_fp) {
- fclose(_fp);
- _fp = NULL;
- }
-}
-
-void *AccurateBuffer::get_elt(int nb)
-{
- int page=nb*sizeof(AccurateElt)/sizeof(_buf);
-
- if (!_fp) {
- init();
- }
-
- if (page != _nb) { /* not the same page */
- if (_dirty) { /* have to sync on disk */
-// printf("put dirty page on disk %i\n", _nb);
- if (fseek(_fp, _nb*sizeof(_buf), SEEK_SET) == -1) {
- perror("bad fseek");
- exit(3);
- }
- if (fwrite(_buf, sizeof(_buf), 1, _fp) != 1) {
- perror("writing...");
- exit(2);
- }
- _dirty=0;
- }
- if (page <= _max_nb) { /* we read it only if the page exists */
-// printf("read page from disk %i <= %i\n", page, _max_nb);
- fseek(_fp, page*sizeof(_buf), SEEK_SET);
- if (fread(_buf, sizeof(_buf), 1, _fp) != 1) {
-// printf("memset to zero\n");
- memset(_buf, 0, sizeof(_buf));
- }
- } else {
- memset(_buf, 0, sizeof(_buf));
- }
- _nb = page;
- _max_nb = MAX(_max_nb, page);
- }
-
- /* compute addr of the element in _buf */
- int addr=(nb%(sizeof(_buf)/sizeof(AccurateElt)))*sizeof(AccurateElt);
-// printf("addr=%i\n", addr);
- return (void *) (_buf + addr);
-}
-
-void AccurateBuffer::update_elt(int nb)
-{
- _dirty = 1;
-}
-
-typedef struct B_DBx
-{
- POOLMEM *fname;
- int fnl;
- POOLMEM *path;
- int pnl;
-} B_DBx;
-
-/*
- * Given a full filename, split it into its path
- * and filename parts. They are returned in pool memory
- * in the mdb structure.
- */
-void split_path_and_file(B_DBx *mdb, const char *fname)
-{
- const char *p, *f;
-
- /* Find path without the filename.
- * I.e. everything after the last / is a "filename".
- * OK, maybe it is a directory name, but we treat it like
- * a filename. If we don't find a / then the whole name
- * must be a path name (e.g. c:).
- */
- for (p=f=fname; *p; p++) {
- if (IsPathSeparator(*p)) {
- f = p; /* set pos of last slash */
- }
- }
- if (IsPathSeparator(*f)) { /* did we find a slash? */
- f++; /* yes, point to filename */
- } else { /* no, whole thing must be path name */
- f = p;
- }
-
- /* If filename doesn't exist (i.e. root directory), we
- * simply create a blank name consisting of a single
- * space. This makes handling zero length filenames
- * easier.
- */
- mdb->fnl = p - f;
- if (mdb->fnl > 0) {
- mdb->fname = check_pool_memory_size(mdb->fname, mdb->fnl+1);
- memcpy(mdb->fname, f, mdb->fnl); /* copy filename */
- mdb->fname[mdb->fnl] = 0;
- } else {
- mdb->fname[0] = 0;
- mdb->fnl = 0;
- }
-
- mdb->pnl = f - fname;
- if (mdb->pnl > 0) {
- mdb->path = check_pool_memory_size(mdb->path, mdb->pnl+1);
- memcpy(mdb->path, fname, mdb->pnl);
- mdb->path[mdb->pnl] = 0;
- } else {
- mdb->path[0] = 0;
- mdb->pnl = 0;
- }
-
- Dmsg2(500, "split path=%s file=%s\n", mdb->path, mdb->fname);
-}
-
-#ifdef _TEST_TREE
-int main()
-{
- AccurateElt *elt;
- char *start_heap = (char *)sbrk(0);
- MY *myp, *res;
- MY_INDEX *idx;
-
- FILE *fp;
- fp = fopen("lst", "r");
- if (!fp) {
- exit (5);
- }
- rblist *index, *rb_file, *rb_path;
- index = New(rblist(idx, &idx->link)); /* (pathid, filenameid) => index */
- rb_path = New(rblist(myp, &myp->link)); /* pathid => path */
- rb_file = New(rblist(myp, &myp->link)); /* filenameid => filename */
-
- B_DBx mdb;
- mdb.fname = get_pool_memory(PM_FNAME);
- mdb.path = get_pool_memory(PM_FNAME);
-
- AccurateBuffer *accbuf = new AccurateBuffer;
- char buf[4096];
- int64_t count=0;
- printf("loading...\n");
- while (fgets(buf, sizeof(buf), fp)) {
- int len = strlen(buf);
- if (len > 0) {
- buf[len-1]=0; /* zap \n */
- }
- split_path_and_file(&mdb, buf);
-
- MY_INDEX *idx = (MY_INDEX *)malloc(sizeof(MY_INDEX));
- memset(idx, 0, sizeof(MY_INDEX));
-
- myp = (MY *)malloc(sizeof(MY));
- memset(myp, 0, sizeof(MY));
- myp->buf = bstrdup(mdb.path);
- res = (MY *)rb_path->insert(myp, my_cmp);
- if (res != myp) {
- free(myp->buf);
- free(myp);
- }
-
- idx->path = res->buf;
-
- myp = (MY *)malloc(sizeof(MY));
- memset(myp, 0, sizeof(MY));
- myp->buf = bstrdup(mdb.fname);
- res = (MY *)rb_file->insert(myp, my_cmp);
- if (res != myp) {
- free(myp->buf);
- free(myp);
- }
-
- idx->fname = res->buf;
-
- idx->index = count;
- index->insert(idx, my_index_cmp);
-
- elt = (AccurateElt *)accbuf->get_elt(count);
- elt->mtime = count;
- elt->path = idx->path;
- elt->fname = idx->fname;
- accbuf->update_elt(count);
-
- count++;
- }
-
- printf("fetch and update...\n");
- fprintf(stderr, "count;%lli\n", count);
- fprintf(stderr, "heap;%lld\n", (long long)((char *)sbrk(0) - start_heap));
-
- fseek(fp, 0, SEEK_SET);
- int toggle=0;
- while (fgets(buf, sizeof(buf), fp)) {
- int len = strlen(buf);
- if (len > 0) {
- buf[len-1]=0; /* zap \n */
- }
- split_path_and_file(&mdb, buf);
-
- MY search;
- search.buf = mdb.fname;
- MY *f = (MY *)rb_file->search(&search, my_cmp);
-
- if (!f) {
- continue; /* not found, skip */
- }
-
- search.buf = mdb.path;
- MY *p = (MY *)rb_path->search(&search, my_cmp);
- if (!p) {
- continue; /* not found, skip */
- }
-
- MY_INDEX idx;
- idx.path = p->buf;
- idx.fname = f->buf;
- MY_INDEX *res = (MY_INDEX *)index->search(&idx, my_index_cmp);
-
- if (!res) {
- continue; /* not found skip */
- }
-
- AccurateElt *elt = (AccurateElt *)accbuf->get_elt(res->index);
- elt->seen=toggle;
- accbuf->update_elt(res->index);
- toggle = (toggle+1)%100000;
- }
-
- for(int j=0;j<=count; j++) {
- AccurateElt *elt = (AccurateElt *)accbuf->get_elt(j);
- if (elt->path && elt->fname) {
- if (!elt->seen) {
- printf("%s%s\n", elt->path, elt->fname);
- }
- }
- }
-}
-#else
-#ifdef _TEST_OPEN
-int main()
-{
- int fd;
- int i;
- AccurateElt elt;
- char *start_heap = (char *)sbrk(0);
-
- fd = open("testfile", O_CREAT | O_RDWR, 0600);
- if (fd<0) {
- perror("E: Can't open testfile ");
- return(1);
- }
-
- memset(&elt, 0, sizeof(elt));
-
- /* 1) Loading */
- for (i=0; i<NB_ELT; i++) {
- write(fd, &elt, sizeof(elt));
- }
-
- lseek(fd, 0, SEEK_SET); /* rewind */
-
- /* 2) load and update */
- for (i=0; i<NB_ELT; i++) {
- lseek(fd, i*sizeof(AccurateElt), SEEK_SET);
- read(fd, &elt, sizeof(elt));
- lseek(fd, i*sizeof(AccurateElt), SEEK_SET);
- write(fd, &elt, sizeof(elt));
- }
-
- lseek(fd, 0, SEEK_SET); /* rewind */
-
- /* 3) Fetch all of them */
- for (i=0; i<NB_ELT; i++) {
- read(fd, &elt, sizeof(elt));
- }
-
- close(fd);
-
- fprintf(stderr, "heap;%lld\n", (long long)((char *)sbrk(0) - start_heap));
- sleep(50);
- return (0);
-}
-#else /* _TEST_OPEN */
-#ifdef _TEST_BUF
-int main()
-{
- char *start_heap = (char *)sbrk(0);
-
- int i;
- AccurateElt *elt;
- AccurateBuffer *buf = new AccurateBuffer;
-
- /* 1) Loading */
- printf("Loading...\n");
- for (i=0; i<NB_ELT; i++) {
- elt = (AccurateElt *) buf->get_elt(i);
- elt->mtime = i;
- buf->update_elt(i);
- }
-
- /* 2) load and update */
- printf("Load and update...\n");
- for (i=0; i<NB_ELT; i++) {
- elt = (AccurateElt *) buf->get_elt(i);
- if (elt->mtime != i) {
- printf("Something is wrong with elt %i mtime=%lli\n", i, elt->mtime);
- exit (0);
- }
- elt->seen = i;
- buf->update_elt(i);
- }
-
- /* 3) Fetch all of them */
- printf("Fetch them...\n");
- for (i=0; i<NB_ELT; i++) {
- elt = (AccurateElt *) buf->get_elt(i);
- if (elt->seen != i || elt->mtime != i) {
- printf("Something is wrong with elt %i mtime=%lli seen=%i\n", i, elt->mtime, elt->seen);
- exit (0);
- }
- }
- fprintf(stderr, "heap;%lld\n", (long long)((char *)sbrk(0) - start_heap));
- delete buf;
-
- return(0);
-}
-
-#else
-int main()
-{
- FILE *fd;
- int i;
- AccurateElt elt;
- fd = fopen("testfile", "w+");
- if (!fd) {
- perror("E: Can't open testfile ");
- return(1);
- }
-
- memset(&elt, 0, sizeof(elt));
-
- /* 1) Loading */
- printf("Loading...\n");
- for (i=0; i<NB_ELT; i++) {
- fwrite(&elt, sizeof(elt), 1, fd);
- }
-
- fseek(fd, 0, SEEK_SET); /* rewind */
-
- /* 2) load and update */
- printf("Load and update...\n");
- for (i=0; i<NB_ELT; i++) {
- fseek(fd, i*sizeof(AccurateElt), SEEK_SET);
- fread(&elt, sizeof(elt), 1, fd);
- fseek(fd, i*sizeof(AccurateElt), SEEK_SET);
- fwrite(&elt, sizeof(elt), 1, fd);
- }
-
- fseek(fd, 0, SEEK_SET); /* rewind */
-
- /* 3) Fetch all of them */
- printf("Fetch them...\n");
- for (i=0; i<NB_ELT; i++) {
- fread(&elt, sizeof(elt), 1, fd);
- }
-
- fclose(fd);
- return(0);
-}
-#endif /* _TEST_BUF */
-#endif /* _TEST_OPEN */
-#endif /* _TEST_TREE */
+++ /dev/null
-#!/usr/bin/env perl
-use strict;
-
-=head1 SCRIPT
-
- This script dumps your Bacula catalog in ASCII format
- It works for MySQL, SQLite, and PostgreSQL
-
-=head1 USAGE
-
- make_catalog_backup.pl MyCatalog
-
-=head1 LICENSE
-
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2000-2008 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.
-
- This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation plus additions
- that are listed in the file LICENSE.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Bacula® is a registered trademark of Kern Sibbald.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zurich,
- Switzerland, email:ftf@fsfeurope.org.
-
-=cut
-
-$ENV{PATH}="@SQL_BINDIR@:$ENV{PATH}";
-
-my $cat = shift or die "Usage: $0 catalogname";
-my $dir_conf='@sbindir@/dbcheck -B -c @sysconfdir@/bacula-dir.conf';
-my $wd = "@working_dir@";
-
-sub dump_sqlite
-{
- my %args = @_;
-
- exec("echo .dump | sqlite '$wd/$args{db_name}.db' > '$wd/$args{db_name}.sql'");
- print "Error while executing sqlite dump $!\n";
- return 1;
-}
-
-sub dump_sqlite3
-{
- my %args = @_;
-
- exec("echo .dump | sqlite3 '$wd/$args{db_name}.db' > '$wd/$args{db_name}.sql'");
- print "Error while executing sqlite dump $!\n";
- return 1;
-}
-
-# TODO: use just ENV and drop the pg_service.conf file
-sub dump_pgsql
-{
- my %args = @_;
- umask(0077);
-
- if ($args{db_address}) {
- $ENV{PGHOST}=$args{db_address};
- }
- if ($args{db_port}) {
- $ENV{PGPORT}=$args{db_port};
- }
-
- $ENV{PGDATABASE}=$args{db_name};
- $ENV{PGUSER}=$args{db_user};
- $ENV{PGPASSWORD}=$args{db_password};
- exec("HOME='$wd' pg_dump -c > '$wd/$args{db_name}.sql'");
- print "Error while executing postgres dump $!\n";
- return 1; # in case of error
-}
-
-sub dump_mysql
-{
- my %args = @_;
- umask(0700);
- unlink("$wd/.my.cnf");
- open(MY, ">$wd/.my.cnf")
- or die "Can't open $wd/.my.cnf for writing $@";
- $args{db_address} = $args{db_address} || "localhost";
- print MY "[client]
-host=$args{db_address}
-user=$args{db_user}
-password=$args{db_password}
-";
- if ($args{db_port}) {
- print MY "port=%args{db_port}\n";
- }
-
- close(MY);
-
- exec("HOME='$wd' mysqldump -f --opt $args{db_name} > '$wd/$args{db_name}.sql'");
- print "Error while executing mysql dump $!\n";
- return 1;
-}
-
-sub dump_catalog
-{
- my %args = @_;
- if ($args{db_type} eq 'SQLite') {
- dump_sqlite(%args);
- } elsif ($args{db_type} eq 'SQLite3') {
- dump_sqlite3(%args);
- } elsif ($args{db_type} eq 'PostgreSQL') {
- dump_pgsql(%args);
- } elsif ($args{db_type} eq 'MySQL') {
- dump_mysql(%args);
- } else {
- die "This database type isn't supported";
- }
-}
-
-open(FP, "$dir_conf|") or die "Can't get catalog information $@";
-# catalog=MyCatalog
-# db_type=SQLite
-# db_name=regress
-# db_driver=
-# db_user=regress
-# db_password=
-# db_address=
-# db_port=0
-# db_socket=
-my %cfg;
-
-while(my $l = <FP>)
-{
- if ($l =~ /catalog=(.+)/) {
- if (exists $cfg{catalog} and $cfg{catalog} eq $cat) {
- exit dump_catalog(%cfg);
- }
- %cfg = (); # reset
- }
-
- if ($l =~ /(\w+)=(.+)/) {
- $cfg{$1}=$2;
- }
-}
-
-if (exists $cfg{catalog} and $cfg{catalog} eq $cat) {
- exit dump_catalog(%cfg);
-}
-
-print "Can't find your catalog ($cat) in director configuration\n";
-exit 1;
+++ /dev/null
-/*
- Bacula® - The Network Backup Solution
-
- Copyright (C) 2006-2008 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.
- This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation and included
- in the file LICENSE.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
- Bacula® is a registered trademark of John Walker.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
-*/
-/*
- * mtops.c - Emulate the Linux st (scsi tape) driver on file.
- * for regression and bug hunting purpose
- *
- * Version $Id$
- *
- */
-
-#include <stdarg.h>
-#include <stddef.h>
-
-#include "bacula.h" /* pull in global headers */
-#include "stored.h" /* pull in Storage Deamon headers */
-
-#include "sys/mtio.h"
-
-//
-// SCSI bus status codes.
-//
-
-#define SCSISTAT_GOOD 0x00
-#define SCSISTAT_CHECK_CONDITION 0x02
-#define SCSISTAT_CONDITION_MET 0x04
-#define SCSISTAT_BUSY 0x08
-#define SCSISTAT_INTERMEDIATE 0x10
-#define SCSISTAT_INTERMEDIATE_COND_MET 0x14
-#define SCSISTAT_RESERVATION_CONFLICT 0x18
-#define SCSISTAT_COMMAND_TERMINATED 0x22
-#define SCSISTAT_QUEUE_FULL 0x28
-
-/*
- * +---+-------+----------------+------------------------+
- * | V | NB FM | FM index tab | Data |
- * +---+-------+----------------+------------------------+
- *
- * V : char version
- * NB FM : int16 max_file_mark
- * FM index : int64 file_mark_index[max_file_mark]
- * DATA : data
- */
-
-typedef struct
-{
- /* format infos */
- int16_t version;
- int16_t max_file_mark;
- int16_t block_size;
- int32_t block_max;
- off_t *file_mark_index;
- off_t data_start;
-
-} FTAPE_FORMAT;
-
-#define FTAPE_HEADER_SIZE (2+sizeof(int16_t))
-
-typedef struct
-{
- int fd : 0; /* Os file descriptor */
- char *file; /* file name */
- bool EOD;
- bool EOF; /* End of file */
- bool EOT; /* End of tape */
-
- FTAPE_FORMAT format;
-
- int16_t current_file; /* max 65000 files */
- int32_t current_block; /* max 4G blocks of 512B */
-
-} FTAPE_INFO;
-
-#define NB_TAPE_LIST 15
-FTAPE_INFO tape_list[NB_TAPE_LIST];
-
-
-static int tape_get(int fd, struct mtget *mt_get);
-static int tape_op(int fd, struct mtop *mt_com);
-static int tape_pos(int fd, struct mtpos *mt_pos);
-
-static int dbglevel = 10;
-
-static FTAPE_INFO *get_tape(int fd)
-{
- if (fd >= NB_TAPE_LIST) {
- /* error */
- return NULL;
- }
-
- return &tape_list[fd];
-}
-
-static FTAPE_INFO *new_volume(int fd, const char *file)
-{
- FTAPE_INFO *tape = get_tape(fd);
- if (!tape) {
- return NULL;
- }
- memset(tape, 0, sizeof(FTAPE_INFO));
-
- tape->fd = fd;
- tape->file = bstrdup(file);
-
- nb = read(tape->fd, &tape->format, FTAPE_HEADER_SIZE);
- if (nb != FTAPE_HEADER_SIZE) { /* new tape ? */
-
- }
- tape->format.file_index = mmap(NULL,
- tape->format.max_file_mark * sizeof(off_t),
- PROT_READ | PROT_WRITE,
- MAP_SHARED, fileno(fd), FTAPE_HEADER_SIZE);
-
- if (!tape->format.file_index) {
- /* error */
- }
-
- tape->format.data_start =
- FTAPE_HEADER_SIZE + sizeof(off_t)* tape->format.max_file_mark ;
-
- return tape;
-}
-
-static int free_volume(int fd)
-{
- FTAPE_INFO *tape = get_tape(fd);
-
- if (tape) {
- munmap(tape->format.file_index, tape->format.max_file_mark * sizeof(off_t));
- free(tape->file);
- free(tape);
- }
-}
-
-int
-fake_tape_open(const char *file, int flags, int mode)
-{
- int fd;
- Dmsg(dbglevel, "fake_tape_open(%s, %i, %i)\n", file, flags, mode);
- fd = open(file, flags, mode);
- new_volume(fd, file);
- return fd;
-}
-
-int
-fake_tape_read(int fd, void *buffer, unsigned int count)
-{
- int ret;
- if (buffer == NULL) {
- errno = EINVAL;
- return -1;
- }
- ret = read(fd, buffer, count);
- return ret;
-}
-
-int
-fake_tape_write(int fd, const void *buffer, unsigned int count)
-{
- int ret;
- if (buffer == NULL) {
- errno = EINVAL;
- return -1;
- }
- ret = write(fd, buffer, count);
- return ret;
-}
-
-int
-fake_tape_close(int fd)
-{
- free_volume(fd);
- close(fd);
- return 0;
-}
-
-int
-fake_tape_ioctl(int fd, unsigned long int request, ...)
-{
- va_list argp;
- int result;
-
- va_start(argp, request);
-
- switch (request) {
- case MTIOCTOP:
- result = tape_op(fd, va_arg(argp, mtop *));
- break;
-
- case MTIOCGET:
- result = tape_get(fd, va_arg(argp, mtget *));
- break;
-
- case MTIOCPOS:
- result = tape_pos(fd, va_arg(argp, mtpos *));
- break;
-
- default:
- errno = ENOTTY;
- result = -1;
- break;
- }
-
- va_end(argp);
-
- return result;
-}
-
-static int tape_op(int fd, struct mtop *mt_com)
-{
- int result;
-
- FTAPE_INFO *tape = get_tape(fd);
- if (!tape) {
- errno = EBADF;
- return -1;
- }
-
- switch (mt_com->mt_op)
- {
- case MTRESET:
- case MTNOP:
- case MTSETDRVBUFFER:
- break;
-
- default:
- case MTRAS1:
- case MTRAS2:
- case MTRAS3:
- case MTSETDENSITY:
- errno = ENOTTY;
- result = (DWORD)-1;
- break;
-
- case MTFSF:
- index = tape->current_file + mt_com->mt_count;
-
- if (index >= tape->max_file_mark) {
- errno = EIO;
- result = -1;
-
- } else {
- tape->current_file = index;
- tape->current_block = 0;
- tape->EOF = true;
- tape->EOT = false;
-
- pos = tape->file_mark_index[index];
- if (lseek(fd, pos, SEEK_SET) == (boffset_t)-1) {
- berrno be;
- dev_errno = errno;
- Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
- print_name(), be.bstrerror());
- result = -1;
- }
- }
- break;
-
- case MTBSF:
- index = tape->current_file - mt_com->mt_count;
-
- if (index < 0 && index => tape->max_file_mark) {
- errno = EIO;
- result = -1;
-
- } else {
- tape->current_file = index;
- tape->current_block = 0;
- tape->EOF = true;
- tape->EOT = false;
-
- pos = tape->file_mark_index[index];
- if (lseek(fd, pos, SEEK_SET) == (boffset_t)-1) {
- berrno be;
- dev_errno = errno;
- Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
- print_name(), be.bstrerror());
- result = -1;
- }
- break;
-
- case MTFSR: /* block forward */
- if ((tape->current_block + mt_com->mt_count) >= tape->block_max) {
- errno = ENOSPC;
- result = -1;
-
- } else { // TODO: check for tape mark
-
- tape->current_block += mt_com->mt_count;
- tape->EOF = false;
- tape->EOT = false;
-
- if (lseek(fd, mt_com->mt_count * tape->format.block_size, SEEK_CUR) == (boffset_t)-1) {
- berrno be;
- dev_errno = errno;
- Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
- print_name(), be.bstrerror());
- result = -1;
- }
- }
-
-//
-// result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_RELATIVE_BLOCKS, 0, mt_com->mt_count, 0, FALSE);
-// if (result == NO_ERROR) {
-// pHandleInfo->bEOD = false;
-// pHandleInfo->bEOF = false;
-// pHandleInfo->bEOT = false;
-// } else if (result == ERROR_FILEMARK_DETECTED) {
-// pHandleInfo->bEOF = true;
-// }
-//
- break;
-
- case MTBSR:
- if ((tape->current_block - mt_com->mt_count) < 0) {
- // we are on tapemark, we have to BSF
- struct mtop mt;
- mt.mt_op = MTBSF;
- mt.mt_count = 1;
- result = tape_op(fd, &mt);
-
- } else {
-
- tape->current_block -= mt_com->mt_count;
- tape->EOF = false;
- tape->EOT = false;
-
- if (lseek(fd, -mt_com->mt_count * tape->format.block_size, SEEK_CUR) == (boffset_t)-1) {
- berrno be;
- dev_errno = errno;
- Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
- print_name(), be.bstrerror());
- result = -1;
- }
- }
- break;
-
- case MTWEOF:
- if (tape->current_file >= tape->format.max_file_mark) {
- errno = ENOSPC;
- result = -1;
- } else {
- tape->current_file++;
- tape->format.file_index[tape->current_file] = ftell(fd);
- tape->EOF = 1;
- }
-
- break;
-
- case MTREW:
- if (lseek(fd, tape->format.data_start, SEEK_SET) < 0) {
- berrno be;
- dev_errno = errno;
- Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
- print_name(), be.bstrerror());
- result = -1 ;
- } else {
- tape->EOF = false;
- result = NO_ERROR;
- }
- break;
-
- case MTOFFL: /* put tape offline */
- // check if can_read/can_write
- result = NO_ERROR;
- break;
-
- case MTRETEN:
- result = NO_ERROR;
- break;
-
- case MTBSFM: /* not used by bacula */
- errno = EIO;
- result = -1;
- break;
-
- case MTFSFM: /* not used by bacula */
- errno = EIO;
- result = -1;
- break;
-
- case MTEOM:
- int i=0;
- int last=0;
- for (i=tape->format.current_file;
- (i < tape->format.max_file_mark) &&(tape->format.file_index[i] != 0) ;
- i++)
- {
- last = i;
- }
-
- struct mtop mt;
- mt.mt_op = MTFSF;
- mt.mt_count = last;
- result = tape_op(fd, &mt);
-
- break;
-
- case MTERASE:
- result = EraseTape(pHandleInfo->OSHandle, TAPE_ERASE_LONG, FALSE);
- if (result == NO_ERROR) {
- pHandleInfo->bEOD = true;
- pHandleInfo->bEOF = false;
- pHandleInfo->bEOT = false;
- pHandleInfo->ulFile = 0;
- pHandleInfo->bBlockValid = true;
- pHandleInfo->ullFileStart = 0;
- }
- break;
-
- case MTSETBLK:
- {
- TAPE_SET_MEDIA_PARAMETERS SetMediaParameters;
-
- SetMediaParameters.BlockSize = mt_com->mt_count;
- result = SetTapeParameters(pHandleInfo->OSHandle, SET_TAPE_MEDIA_INFORMATION, &SetMediaParameters);
- }
- break;
-
- case MTSEEK:
- {
- TAPE_POSITION_INFO TapePositionInfo;
-
- result = SetTapePosition(pHandleInfo->OSHandle, TAPE_ABSOLUTE_BLOCK, 0, mt_com->mt_count, 0, FALSE);
-
- memset(&TapePositionInfo, 0, sizeof(TapePositionInfo));
- DWORD dwPosResult = GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo);
- if (dwPosResult == NO_ERROR && TapePositionInfo.FileSetValid) {
- pHandleInfo->ulFile = (ULONG)TapePositionInfo.FileNumber;
- } else {
- pHandleInfo->ulFile = ~0U;
- }
- }
- break;
-
- case MTTELL:
- {
- DWORD partition;
- DWORD offset;
- DWORD offsetHi;
-
- result = GetTapePosition(pHandleInfo->OSHandle, TAPE_ABSOLUTE_BLOCK, &partition, &offset, &offsetHi);
- if (result == NO_ERROR) {
- return offset;
- }
- }
- break;
-
- case MTFSS:
- result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_SETMARKS, 0, mt_com->mt_count, 0, FALSE);
- break;
-
- case MTBSS:
- result = SetTapePosition(pHandleInfo->OSHandle, TAPE_SPACE_SETMARKS, 0, -mt_com->mt_count, ~0, FALSE);
- break;
-
- case MTWSM:
- result = WriteTapemark(pHandleInfo->OSHandle, TAPE_SETMARKS, mt_com->mt_count, FALSE);
- break;
-
- case MTLOCK:
- result = PrepareTape(pHandleInfo->OSHandle, TAPE_LOCK, FALSE);
- break;
-
- case MTUNLOCK:
- result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOCK, FALSE);
- break;
-
- case MTLOAD:
- result = PrepareTape(pHandleInfo->OSHandle, TAPE_LOAD, FALSE);
- break;
-
- case MTUNLOAD:
- result = PrepareTape(pHandleInfo->OSHandle, TAPE_UNLOAD, FALSE);
- break;
-
- case MTCOMPRESSION:
- {
- TAPE_GET_DRIVE_PARAMETERS GetDriveParameters;
- TAPE_SET_DRIVE_PARAMETERS SetDriveParameters;
- DWORD size;
-
- size = sizeof(GetDriveParameters);
-
- result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &size, &GetDriveParameters);
-
- if (result == NO_ERROR)
- {
- SetDriveParameters.ECC = GetDriveParameters.ECC;
- SetDriveParameters.Compression = (BOOLEAN)mt_com->mt_count;
- SetDriveParameters.DataPadding = GetDriveParameters.DataPadding;
- SetDriveParameters.ReportSetmarks = GetDriveParameters.ReportSetmarks;
- SetDriveParameters.EOTWarningZoneSize = GetDriveParameters.EOTWarningZoneSize;
-
- result = SetTapeParameters(pHandleInfo->OSHandle, SET_TAPE_DRIVE_INFORMATION, &SetDriveParameters);
- }
- }
- break;
-
- case MTSETPART:
- result = SetTapePosition(pHandleInfo->OSHandle, TAPE_LOGICAL_BLOCK, mt_com->mt_count, 0, 0, FALSE);
- break;
-
- case MTMKPART:
- if (mt_com->mt_count == 0)
- {
- result = CreateTapePartition(pHandleInfo->OSHandle, TAPE_INITIATOR_PARTITIONS, 1, 0);
- }
- else
- {
- result = CreateTapePartition(pHandleInfo->OSHandle, TAPE_INITIATOR_PARTITIONS, 2, mt_com->mt_count);
- }
- break;
- }
-
- if ((result == NO_ERROR && pHandleInfo->bEOF) ||
- (result == ERROR_FILEMARK_DETECTED && mt_com->mt_op == MTFSR)) {
-
- TAPE_POSITION_INFO TapePositionInfo;
-
- if (GetTapePositionInfo(pHandleInfo->OSHandle, &TapePositionInfo) == NO_ERROR) {
- pHandleInfo->bBlockValid = true;
- pHandleInfo->ullFileStart = TapePositionInfo.BlockNumber;
- }
- }
-
- switch (result) {
- case NO_ERROR:
- case (DWORD)-1: /* Error has already been translated into errno */
- break;
-
- default:
- case ERROR_FILEMARK_DETECTED:
- errno = EIO;
- break;
-
- case ERROR_END_OF_MEDIA:
- pHandleInfo->bEOT = true;
- errno = EIO;
- break;
-
- case ERROR_NO_DATA_DETECTED:
- pHandleInfo->bEOD = true;
- errno = EIO;
- break;
-
- case ERROR_NO_MEDIA_IN_DRIVE:
- pHandleInfo->bEOF = false;
- pHandleInfo->bEOT = false;
- pHandleInfo->bEOD = false;
- errno = ENOMEDIUM;
- break;
-
- case ERROR_INVALID_HANDLE:
- case ERROR_ACCESS_DENIED:
- case ERROR_LOCK_VIOLATION:
- errno = EBADF;
- break;
- }
-
- return result == NO_ERROR ? 0 : -1;
-}
-
-static int tape_get(int fd, struct mtget *mt_get)
-{
- TAPE_POSITION_INFO pos_info;
- BOOL result;
-
- if (fd < 3 || fd >= (int)(NUMBER_HANDLE_ENTRIES + 3) ||
- TapeHandleTable[fd - 3].OSHandle == INVALID_HANDLE_VALUE) {
- errno = EBADF;
- return -1;
- }
-
- PTAPE_HANDLE_INFO pHandleInfo = &TapeHandleTable[fd - 3];
-
- if (GetTapePositionInfo(pHandleInfo->OSHandle, &pos_info) != NO_ERROR) {
- return -1;
- }
-
- DWORD density = 0;
- DWORD blocksize = 0;
-
- result = GetDensityBlockSize(pHandleInfo->OSHandle, &density, &blocksize);
-
- if (result != NO_ERROR) {
- TAPE_GET_DRIVE_PARAMETERS drive_params;
- DWORD size;
-
- size = sizeof(drive_params);
-
- result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_DRIVE_INFORMATION, &size, &drive_params);
-
- if (result == NO_ERROR) {
- blocksize = drive_params.DefaultBlockSize;
- }
- }
-
- mt_get->mt_type = MT_ISSCSI2;
-
- // Partition #
- mt_get->mt_resid = pos_info.PartitionBlockValid ? pos_info.Partition : (ULONG)-1;
-
- // Density / Block Size
- mt_get->mt_dsreg = ((density << MT_ST_DENSITY_SHIFT) & MT_ST_DENSITY_MASK) |
- ((blocksize << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK);
-
- mt_get->mt_gstat = 0x00010000; /* Immediate report mode.*/
-
- if (pHandleInfo->bEOF) {
- mt_get->mt_gstat |= 0x80000000; // GMT_EOF
- }
-
- if (pos_info.PartitionBlockValid && pos_info.BlockNumber == 0) {
- mt_get->mt_gstat |= 0x40000000; // GMT_BOT
- }
-
- if (pHandleInfo->bEOT) {
- mt_get->mt_gstat |= 0x20000000; // GMT_EOT
- }
-
- if (pHandleInfo->bEOD) {
- mt_get->mt_gstat |= 0x08000000; // GMT_EOD
- }
-
- TAPE_GET_MEDIA_PARAMETERS media_params;
- DWORD size = sizeof(media_params);
-
- result = GetTapeParameters(pHandleInfo->OSHandle, GET_TAPE_MEDIA_INFORMATION, &size, &media_params);
-
- if (result == NO_ERROR && media_params.WriteProtected) {
- mt_get->mt_gstat |= 0x04000000; // GMT_WR_PROT
- }
-
- result = GetTapeStatus(pHandleInfo->OSHandle);
-
- if (result != NO_ERROR) {
- if (result == ERROR_NO_MEDIA_IN_DRIVE) {
- mt_get->mt_gstat |= 0x00040000; // GMT_DR_OPEN
- }
- } else {
- mt_get->mt_gstat |= 0x01000000; // GMT_ONLINE
- }
-
- // Recovered Error Count
- mt_get->mt_erreg = 0;
-
- // File Number
- mt_get->mt_fileno = (__daddr_t)pHandleInfo->ulFile;
-
- // Block Number
- mt_get->mt_blkno = (__daddr_t)(pHandleInfo->bBlockValid ? pos_info.BlockNumber - pHandleInfo->ullFileStart : (ULONGLONG)-1);
-
- return 0;
-}
+++ /dev/null
-Index: src/dird/next_vol.c
-===================================================================
---- src/dird/next_vol.c (revision 7929)
-+++ src/dird/next_vol.c (working copy)
-@@ -94,33 +94,31 @@
- */
- if (prune) {
- Dmsg0(150, "Call prune_volumes\n");
-- ok = prune_volumes(jcr, InChanger, mr);
-+ prune_volumes(jcr, InChanger, mr);
- }
-- if (!ok) {
-- ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
-- if (!ok && create) {
-- Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n",
-- ok, index, InChanger, mr->VolStatus);
-- /*
-- * 5. Try pulling a volume from the Scratch pool
-- */
-- ok = get_scratch_volume(jcr, InChanger, mr);
-- Dmsg4(050, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n",
-- ok, index, InChanger, mr->VolStatus);
-- }
-- /*
-- * If we are using an Autochanger and have not found
-- * a volume, retry looking for any volume.
-- */
-- if (!ok && InChanger) {
-- InChanger = false;
-- continue; /* retry again accepting any volume */
-- }
-- }
-+
-+ ok = recycle_oldest_purged_volume(jcr, InChanger, mr);
-+ if (!ok && create) {
-+ Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n",
-+ ok, index, InChanger, mr->VolStatus);
-+ /*
-+ * 5. Try pulling a volume from the Scratch pool
-+ */
-+ ok = get_scratch_volume(jcr, InChanger, mr);
-+ Dmsg4(050, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n",
-+ ok, index, InChanger, mr->VolStatus);
-+ }
-+ /*
-+ * If we are using an Autochanger and have not found
-+ * a volume, retry looking for any volume.
-+ */
-+ if (!ok && InChanger) {
-+ InChanger = false;
-+ continue; /* retry again accepting any volume */
-+ }
- }
- }
-
--
- if (!ok && create) {
- /*
- * 6. Try "creating" a new Volume
-Index: src/dird/autoprune.c
-===================================================================
---- src/dird/autoprune.c (revision 7929)
-+++ src/dird/autoprune.c (working copy)
-@@ -196,6 +196,13 @@
- }
-
- /*
-+ * Continue if this volume is not usable
-+ */
-+ if (ok && !lmr.Recycle) {
-+ ok = false;
-+ }
-+
-+ /*
- * If purged and not moved to another Pool,
- * then we stop pruning and take this volume.
- */
+++ /dev/null
-Index: src/lib/message.c
-===================================================================
---- src/lib/message.c (révision 6325)
-+++ src/lib/message.c (copie de travail)
-@@ -590,6 +590,55 @@
- return true;
- }
-
-+static bool dispatch_it(JCR *jcr, int type, DEST *d)
-+{
-+ bool ret=true;
-+
-+ if (!bit_is_set(type, d->msg_types)) {
-+ return false;
-+ }
-+
-+ /* check if M_FILTER are set */
-+ int max=0;
-+ set_bit(M_MAX, max);
-+
-+ if (d->msg_types <= max) {
-+ return true;
-+ }
-+
-+ /* check this if msg_types contains a level */
-+ switch (jcr->JobLevel) {
-+ case L_FULL:
-+ ret = bit_is_set(M_FILTER_FULL, d->msg_types);
-+ break;
-+
-+ case L_DIFFERENTIAL:
-+ ret = bit_is_set(M_FILTER_DIFFERENTIAL, d->msg_types);
-+ break;
-+
-+ case L_INCREMENTAL:
-+ ret = bit_is_set(M_FILTER_INCREMENTAL, d->msg_types);
-+ break;
-+ }
-+
-+ /* check this if msg_types contains a jobtype */
-+ switch (jcr->JobType) {
-+ case JT_BACKUP:
-+ ret = bit_is_set(M_FILTER_BACKUP, d->msg_types);
-+ break;
-+ case JT_VERIFY:
-+ ret = bit_is_set(M_FILTER_VERIFY, d->msg_types);
-+ break;
-+ case JT_RESTORE:
-+ ret = bit_is_set(M_FILTER_RESTORE, d->msg_types);
-+ break;
-+ case JT_MIGRATED_JOB:
-+ ret = bit_is_set(M_FILTER_MIGRATION, d->msg_types);
-+ break;
-+ }
-+
-+}
-+
- /*
- * Handle sending the message to the appropriate place
- */
-@@ -649,7 +698,8 @@
- msgs = daemon_msgs;
- }
- for (d=msgs->dest_chain; d; d=d->next) {
-- if (bit_is_set(type, d->msg_types)) {
-+ /* check for filter her */
-+ if (dispatch_it(jcr, type, d)) {
- switch (d->dest_code) {
- case MD_CATALOG:
- char ed1[50];
-Index: src/lib/message.h
-===================================================================
---- src/lib/message.h (révision 6325)
-+++ src/lib/message.h (copie de travail)
-@@ -97,15 +97,27 @@
- M_RESTORED, /* ls -l of restored files */
- M_SECURITY, /* security violation */
- M_ALERT, /* tape alert messages */
-- M_VOLMGMT /* Volume management messages */
--};
-+ M_VOLMGMT, /* Volume management messages */
-
-+ /* following options are used as filter */
-+ M_FILTER_VERIFY, /* verify job */
-+ M_FILTER_ADMIN, /* admin job */
-+ M_FILTER_RESTORE, /* restore job */
-+ M_FILTER_MIGRATION, /* migration job */
-+ M_FILTER_BACKUP, /* backup job */
-+ M_FILTER_INCREMENTAL, /* incremental backup job */
-+ M_FILTER_DIFFERENTIAL, /* differential backup job */
-+ M_FILTER_FULL, /* full backup job */
-+ M_FILTER_ALL /* all */
-+};
-+
- #define M_MAX M_VOLMGMT /* keep this updated ! */
-
- /* Define message destination structure */
- /* *** FIXME **** where should be extended to handle multiple values */
- typedef struct s_dest {
- struct s_dest *next;
-+ int filter; /* message filter (M_FILTER_) */
- int dest_code; /* destination (one of the MD_ codes) */
- int max_len; /* max mail line length */
- FILE *fd; /* file descriptor */
-Index: src/lib/parse_conf.c
-===================================================================
---- src/lib/parse_conf.c (révision 6325)
-+++ src/lib/parse_conf.c (copie de travail)
-@@ -152,6 +152,16 @@
- {"all", M_MAX+1},
- {NULL, 0}
- };
-+/* following types are used as message filter */
-+static struct s_mfilters msg_filters[] = {
-+ {"admin", M_FILTER_ADMIN},
-+ {"verify" M_FILTER_VERIFY},
-+ {"restore", M_FILTER_RESTORE},
-+ {"full", M_FILTER_FULL},
-+ {"incremental", M_FILTER_INCREMENTAL},
-+ {"differential", M_FILTER_DIFFERENTIAL},
-+ {NULL, 0}
-+};
-
- /* Used for certain KeyWord tables */
- struct s_kw {
-@@ -331,6 +341,7 @@
- int i;
- bool found, is_not;
- int msg_type = 0;
-+ int msg_filter = 0;
- char *str;
-
- for ( ;; ) {
+++ /dev/null
-diff -Naur cvs/src/baconfig.h my/src/baconfig.h
---- cvs/src/baconfig.h 2006-12-30 17:01:49.000000000 +0100
-+++ my/src/baconfig.h 2006-12-30 17:01:34.000000000 +0100
-@@ -571,10 +571,12 @@
- * Replace codes needed in both file routines and non-file routines
- * Job replace codes -- in "replace"
- */
--#define REPLACE_ALWAYS 'a'
--#define REPLACE_IFNEWER 'w'
--#define REPLACE_NEVER 'n'
--#define REPLACE_IFOLDER 'o'
-+#define REPLACE_ALWAYS 'a'
-+#define REPLACE_IFNEWER 'w'
-+#define REPLACE_NEVER 'n'
-+#define REPLACE_IFOLDER 'o'
-+#define REPLACE_ATTR_ALWAYS 'r'
-+#define REPLACE_ATTR_IFEXISTS 's'
-
- /* This probably should be done on a machine by machine basis, but it works */
- /* This is critical for the smartalloc routines to properly align memory */
-diff -Naur cvs/src/dird/dird_conf.c my/src/dird/dird_conf.c
---- cvs/src/dird/dird_conf.c 2006-12-22 20:47:00.000000000 +0100
-+++ my/src/dird/dird_conf.c 2006-12-30 17:30:42.000000000 +0100
-@@ -467,6 +467,8 @@
- {"ifnewer", REPLACE_IFNEWER},
- {"ifolder", REPLACE_IFOLDER},
- {"never", REPLACE_NEVER},
-+ {"attributes", REPLACE_ATTR_ALWAYS},
-+ {"attributesifexists", REPLACE_ATTR_IFEXISTS},
- {NULL, 0}
- };
-
-diff -Naur cvs/src/filed/restore.c my/src/filed/restore.c
---- cvs/src/filed/restore.c 2006-12-21 13:53:48.000000000 +0100
-+++ my/src/filed/restore.c 2006-12-30 17:22:29.000000000 +0100
-@@ -383,6 +383,12 @@
- extract = true;
- }
- #endif
-+ if (jcr->replace == REPLACE_ATTR_ALWAYS ||
-+ jcr->replace == REPLACE_ATTR_IFEXISTS)
-+ {
-+ extract = false; /* we just want attributes */
-+ }
-+
- if (!extract) {
- /* set attributes now because file will not be extracted */
- set_attributes(jcr, attr, &bfd);
-diff -Naur cvs/src/findlib/create_file.c my/src/findlib/create_file.c
---- cvs/src/findlib/create_file.c 2006-12-20 20:48:59.000000000 +0100
-+++ my/src/findlib/create_file.c 2006-12-30 17:29:17.000000000 +0100
-@@ -135,9 +135,17 @@
- Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
- return CF_SKIP;
-
-+ case REPLACE_ATTR_ALWAYS:
-+ return CF_CREATED;
-+
- case REPLACE_ALWAYS:
- break;
- }
-+ } else { /* File doesn't exists anymore */
-+ if (replace == REPLACE_ATTR_IFEXISTS) {
-+ Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Doesn't exists anymore: %s\n"), attr->ofname);
-+ return CF_SKIP;
-+ }
- }
- switch (attr->type) {
- case FT_RAW: /* raw device to be written */
+++ /dev/null
-From: Eric Bollengier <eric at homelinux dot org>
-
-This patch implements the restore attributes only project.
-To use it, you can select replace = attributes|attributesifexists
-when you run your restore job.
-
-$Log$
-Revision 1.1 2006/12/30 17:18:33 ricozz
-ebl Works with 1.39.35
-
+++ /dev/null
-Index: scripts/cleanup-tape.in
-===================================================================
---- scripts/cleanup-tape.in (révision 7994)
-+++ scripts/cleanup-tape.in (copie de travail)
-@@ -12,16 +12,16 @@
- init_slot @tape_drive@ $SLOT1
-
- if test x@autochanger@ != x/dev/null; then
-- slot=`bin/@changer_script@ @autochanger@ loaded 0 @tape_drive@ $DRIVE1`
-+ slot=`$scripts/@changer_script@ @autochanger@ loaded 0 @tape_drive@ $DRIVE1`
- case $slot in
- 0)
-- bin/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
- ;;
- $SLOT1)
- ;;
- *)
-- bin/@changer_script@ @autochanger@ unload $slot @tape_drive@ $DRIVE1
-- bin/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ unload $slot @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
- ;;
- esac
- fi
-Index: scripts/prepare-two-tapes.in
-===================================================================
---- scripts/prepare-two-tapes.in (révision 7994)
-+++ scripts/prepare-two-tapes.in (copie de travail)
-@@ -18,10 +18,10 @@
- # optimize so we don't unnecessarily unload and load slots
- #
- if test x@autochanger@ != x/dev/null; then
-- slot=`bin/@changer_script@ @autochanger@ loaded 0 @tape_drive@ $DRIVE1`
-+ slot=`$scripts/@changer_script@ @autochanger@ loaded 0 @tape_drive@ $DRIVE1`
- case $slot in
- 0)
-- bin/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
- slot=$SLOT1
- ;;
- $SLOT1)
-@@ -31,22 +31,22 @@
- slot=$SLOT2
- ;;
- *)
-- bin/@changer_script@ @autochanger@ unload $slot @tape_drive@ $DRIVE1
-- bin/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ unload $slot @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
- slot=$SLOT1
- ;;
- esac
- init_drive @tape_drive@
-- bin/@changer_script@ @autochanger@ unload $slot @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ unload $slot @tape_drive@ $DRIVE1
-
-
- # init the other slot
- case $slot in
- $SLOT1)
-- bin/@changer_script@ @autochanger@ load $SLOT2 @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ load $SLOT2 @tape_drive@ $DRIVE1
- ;;
- $SLOT2)
-- bin/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
-+ $scripts/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ $DRIVE1
- ;;
- *)
- echo "Something went wrong. Expected $SLOT1 or $SLOT2, got $slot"
-Index: scripts/check_for_zombie_jobs
-===================================================================
---- scripts/check_for_zombie_jobs (révision 7994)
-+++ scripts/check_for_zombie_jobs (copie de travail)
-@@ -14,7 +14,7 @@
- client=${HOST}-fd
- fi
-
--bin/bconsole -c bin/bconsole.conf <<END_OF_DATA 2>&1 >/dev/null
-+$bin/bconsole -c bin/bconsole.conf <<END_OF_DATA 2>&1 >/dev/null
- @output tmp/dir.out
- status dir
- @output tmp/fd.out
-Index: scripts/prepare-other-loc
-===================================================================
---- scripts/prepare-other-loc (révision 8011)
-+++ scripts/prepare-other-loc (copie de travail)
-@@ -5,8 +5,8 @@
- SCR=$cwd/bin/bacula-ctl
- sed "s:BACDIRBIN=$cwd/bin:BACDIRBIN=$bin:" $SCR-dir > tmp/1
- mv tmp/1 $SCR-dir
--se d -i "s:BACSDBIN=$cwd/bin:BACSDBIN=$bin:" $SCR-sd > tmp/1
--mv tm p/1 $SCR-sd
-+sed -i "s:BACSDBIN=$cwd/bin:BACSDBIN=$bin:" $SCR-sd > tmp/1
-+mv tmp/1 $SCR-sd
- sed -i "s:BACFDBIN=$cwd/bin:BACFDBIN=$bin:" $SCR-fd > tmp/1
- mv tmp/1 $SCR-fd
- chmod -x $cwd/bin/bacula-{fd,sd,dir} $cwd/bin/bconsole
-Index: scripts/setup
-===================================================================
---- scripts/setup (révision 7994)
-+++ scripts/setup (copie de travail)
-@@ -20,6 +20,7 @@
- exit 1
- fi
-
-+# we build and setup binaries to the $cwd/bin directory not $bin
- rm -rf build bin
- # Copy new source
- echo "Copying source from ${BACULA_SOURCE}"
-Index: scripts/cleanup-2drive.in
-===================================================================
---- scripts/cleanup-2drive.in (révision 7994)
-+++ scripts/cleanup-2drive.in (copie de travail)
-@@ -6,40 +6,40 @@
- scripts/cleanup
-
- if test x@autochanger@ != x/dev/null; then
-- slot=`bin/@changer_script@ @autochanger@ loaded 0 @tape_drive1@ 1`
-+ slot=`$scripts/@changer_script@ @autochanger@ loaded 0 @tape_drive1@ 1`
- echo "Slot $slot in drive 1"
- if test x$slot != x0 ; then
- echo "unload slot $slot in drive 1"
-- bin/@changer_script@ @autochanger@ unload $slot @tape_drive1@ 1
-+ $scripts/@changer_script@ @autochanger@ unload $slot @tape_drive1@ 1
- fi
-- slot=`bin/@changer_script@ @autochanger@ loaded 0 @tape_drive@ 0`
-+ slot=`$scripts/@changer_script@ @autochanger@ loaded 0 @tape_drive@ 0`
- echo "Slot $slot in drive 0"
- if test x$slot != x0 ; then
- echo "unload slot $slot in drive 0"
-- bin/@changer_script@ @autochanger@ unload $slot @tape_drive@ 0
-+ $scripts/@changer_script@ @autochanger@ unload $slot @tape_drive@ 0
- fi
-
-
-- slot=`bin/@changer_script@ @autochanger@ loaded 0 @tape_drive1@ 1`
-+ slot=`$scripts/@changer_script@ @autochanger@ loaded 0 @tape_drive1@ 1`
- if test x$slot != x$SLOT2; then
- echo "load slot $SLOT2 in drive 1"
-- bin/@changer_script@ @autochanger@ load $SLOT2 @tape_drive1@ 1
-+ $scripts/@changer_script@ @autochanger@ load $SLOT2 @tape_drive1@ 1
- fi
- echo "WEOF drive 1"
- init_drive @tape_drive1@
-
- echo "unload slot $SLOT2 in drive 1"
-- bin/@changer_script@ @autochanger@ unload $SLOT2 @tape_drive1@ 1
-+ $scripts/@changer_script@ @autochanger@ unload $SLOT2 @tape_drive1@ 1
-
-- slot=`bin/@changer_script@ @autochanger@ loaded 0 @tape_drive@ 0`
-+ slot=`$scripts/@changer_script@ @autochanger@ loaded 0 @tape_drive@ 0`
- echo "Slot $slot in drive 0"
- if test x$slot != x$SLOT1; then
- echo "load slot $SLOT1 in drive 0"
-- bin/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ 0
-+ $scripts/@changer_script@ @autochanger@ load $SLOT1 @tape_drive@ 0
- fi
- echo "WEOF drive 0"
- init_drive @tape_drive@
-
- echo "unload slot $SLOT1 from drive 0"
-- bin/@changer_script@ @autochanger@ unload $SLOT1 @tape_drive@ 0
-+ $scripts/@changer_script@ @autochanger@ unload $SLOT1 @tape_drive@ 0
- fi
-Index: scripts/functions
-===================================================================
---- scripts/functions (révision 7994)
-+++ scripts/functions (copie de travail)
-@@ -10,11 +10,11 @@
- echo "s% mail =%# mail = %g" >${outf}
- echo "s% operator =%# operator =%g" >>${outf}
- cp bin/bacula-dir.conf tmp/1
-- sed -f ${outf} tmp/1 >bin/bacula-dir.conf
-+ sed -f ${outf} tmp/1 > bin/bacula-dir.conf
- echo " "
- echo " "
- echo " === Starting $TestName at `date +%R:%S` ==="
-- echo " === Starting $TestName at `date +%R:%S` ===" >>working/log
-+ echo " === Starting $TestName at `date +%R:%S` ===" >> working/log
- echo " "
- export zstat
- }
-@@ -147,11 +147,11 @@
- bin/bacula-ctl-sd start
- bin/bacula-ctl-fd start $1
- bin/bacula-ctl-dir start
-- cat tmp/bconcmds | bin/bconsole -c bin/bconsole.conf
-+ cat tmp/bconcmds | $bin/bconsole -c bin/bconsole.conf
- return $?
- else
-- bin/bacula start 2>&1 >/dev/null
-- cat tmp/bconcmds | bin/bconsole -c bin/bconsole.conf 2>&1 >/dev/null
-+ bin/bacula start >/dev/null 2>&1
-+ cat tmp/bconcmds | $bin/bconsole -c bin/bconsole.conf >/dev/null 2>&1
- return $?
- fi
- }
-@@ -159,27 +159,27 @@
- run_bconsole()
- {
- if test "$debug" -eq 1 ; then
-- cat tmp/bconcmds | bin/bconsole -c bin/bconsole.conf
-+ cat tmp/bconcmds | $bin/bconsole -c bin/bconsole.conf
- else
-- cat tmp/bconcmds | bin/bconsole -c bin/bconsole.conf 2>&1 >/dev/null
-+ cat tmp/bconcmds | $bin/bconsole -c bin/bconsole.conf 2>&1 >/dev/null
- fi
- }
-
- run_btape()
- {
- if test "$debug" -eq 1 ; then
-- cat tmp/bconcmds | bin/btape -c bin/bacula-sd.conf DDS-4 | tee tmp/log1.out
-+ cat tmp/bconcmds | $bin/btape -c bin/bacula-sd.conf DDS-4 | tee tmp/log1.out
- else
-- cat tmp/bconcmds | bin/btape -c bin/bacula-sd.conf DDS-4 2>&1 >tmp/log1.out
-+ cat tmp/bconcmds | $bin/btape -c bin/bacula-sd.conf DDS-4 >tmp/log1.out 2>&1
- fi
- }
-
- run_bscan()
- {
- if test "$debug" -eq 1 ; then
-- bin/bscan $* | tee tmp/log.out
-+ $bin/bscan $* | tee tmp/log.out
- else
-- bin/bscan $* 2>&1 >/dev/null
-+ $bin/bscan $* 2>&1 >/dev/null
- fi
- }
-
-@@ -356,10 +356,10 @@
- load_slot1()
- {
- # Get a tape from slot1
--slot=`bin/$MTX ${AUTOCHANGER} loaded 0 ${TAPE_DRIVE} $DRIVE1`
-+slot=`$scripts/$MTX ${AUTOCHANGER} loaded 0 ${TAPE_DRIVE} $DRIVE1`
- case $slot in
- 0)
-- bin/$MTX ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
-+ $scripts/$MTX ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
- slot=$SLOT1
- ;;
- $SLOT1)
-@@ -367,8 +367,8 @@
- ;;
- *)
- rewind_drive ${TAPE_DRIVE}
-- bin/$MTX ${AUTOCHANGER} unload $slot ${TAPE_DRIVE} $DRIVE1
-- bin/$MTX ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
-+ $scripts/$MTX ${AUTOCHANGER} unload $slot ${TAPE_DRIVE} $DRIVE1
-+ $scripts/$MTX ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
- slot=$SLOT1
- ;;
- esac
-@@ -383,17 +383,17 @@
- rewind_drive ${TAPE_DRIVE}
- case $1 in
- 0)
-- bin/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
-+ $scripts/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
- slot=1
- ;;
- $SLOT1)
-- bin/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $1 ${TAPE_DRIVE} $DRIVE1
-- bin/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT2 ${TAPE_DRIVE} $DRIVE1
-+ $scripts/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $1 ${TAPE_DRIVE} $DRIVE1
-+ $scripts/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT2 ${TAPE_DRIVE} $DRIVE1
- slot=2
- ;;
- $SLOT2)
-- bin/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $1 ${TAPE_DRIVE} $DRIVE1
-- bin/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
-+ $scripts/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $1 ${TAPE_DRIVE} $DRIVE1
-+ $scripts/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} load $SLOT1 ${TAPE_DRIVE} $DRIVE1
- slot=1
- ;;
- *)
-@@ -403,7 +403,6 @@
- esac
- }
-
--
- # Save current directory
- cwd=`pwd`
- if test "x${REGRESS_DEBUG}" = "x1"; then
-@@ -418,16 +417,23 @@
- db_name=${db_name:-"regress"}
- db_user=${db_user:-"regress"}
- db_password=${db_password:-""}
-+working=${working:-"$cwd/working"}
-+bin=${bin:-"$cwd/bin"}
-+scripts=${scripts:-"$bin"}
-
-+export bin
-+export working
-+export scripts
-+
- CLIENT=${HOST}-fd
-
- if [ x$USE_VTAPE = xyes ]; then
-- mkdir -p $cwd/working/ach
-+ mkdir -p $working/ach
- SLOT1=1
- SLOT2=2
-- TAPE_DRIVE=$cwd/working/ach/drive1
-- TAPE_DRIVE1=$cwd/working/ach/drive1
-- AUTOCHANGER=$cwd/working/ach/config
-+ TAPE_DRIVE=$working/ach/drive1
-+ TAPE_DRIVE1=$working/ach/drive1
-+ AUTOCHANGER=$working/ach/config
- AUTOCHANGER_SCRIPT=disk-changer
- DRIVE1=0
- DRIVE2=1
-@@ -438,6 +444,6 @@
- fi
-
- AUTOCHANGER_SCRIPT=${AUTOCHANGER_SCRIPT:-mtx-changer}
--LD_LIBRARY_PATH=$cwd/bin
-+LD_LIBRARY_PATH=$bin
- export LD_LIBRARY_PATH
-
-Index: tests/btape-fill-full-tape
-===================================================================
---- tests/btape-fill-full-tape (révision 7994)
-+++ tests/btape-fill-full-tape (copie de travail)
-@@ -14,7 +14,7 @@
- change_jobname $JobName
- start_test
-
--bin/btape -c bin/bacula-sd.conf DDS-4 <<END_OF_DATA 2>&1 >${cwd}/tmp/log1.out
-+$bin/btape -c bin/bacula-sd.conf DDS-4 <<END_OF_DATA >${cwd}/tmp/log1.out 2>&1
- fill
- s
-
-@@ -22,7 +22,7 @@
- END_OF_DATA
-
-
--grep "^The last block on the tape matches\. Test succeeded\." ${cwd}/tmp/log1.out 2>&1 >/dev/null
-+grep "^The last block on the tape matches\. Test succeeded\." ${cwd}/tmp/log1.out >/dev/null 2>&1
- if [ $? != 0 ] ; then
- echo " "
- echo " "
-Index: tests/disk-changer-test
-===================================================================
---- tests/disk-changer-test (révision 7994)
-+++ tests/disk-changer-test (copie de travail)
-@@ -3,43 +3,43 @@
- mkdir tmp/disk-changer
- touch tmp/disk-changer/conf
- echo "Unload drive 0"
--bin/disk-changer tmp/disk-changer/conf unload 1 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf unload 1 tmp/disk-changer/drive0 0
- echo "rtn=$?"
- echo "Test what is in drive 0"
--bin/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive0 0
- echo "rtn=$?"
- echo "Load Slot 1 into drive 0"
--bin/disk-changer tmp/disk-changer/conf load 1 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf load 1 tmp/disk-changer/drive0 0
- echo "rtn=$?"
- echo "Test what is in drive 0"
--bin/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive0 0
- echo "rtn=$?"
-
- echo "Unload drive 1"
--bin/disk-changer tmp/disk-changer/conf unload 2 tmp/disk-changer/drive1 1
-+$scripts/disk-changer tmp/disk-changer/conf unload 2 tmp/disk-changer/drive1 1
- echo "rtn=$?"
- echo "Test what is in drive 1"
--bin/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive1 1
-+$scripts/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive1 1
- echo "rtn=$?"
- echo "Load Slot 2 drive 1"
--bin/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive1 1
-+$scripts/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive1 1
- echo "rtn=$?"
- echo "Test what is in drive 1"
--bin/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive1 1
-+$scripts/disk-changer tmp/disk-changer/conf loaded 1 tmp/disk-changer/drive1 1
- echo "rtn=$?"
-
- echo "Load Slot 1 into drive 0 -- error"
--bin/disk-changer tmp/disk-changer/conf load 1 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf load 1 tmp/disk-changer/drive0 0
- echo "rtn=$?"
- echo "Load Slot 2 into drive 1 -- error"
--bin/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive1 1
-+$scripts/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive1 1
- echo "rtn=$?"
- echo "Load Slot 2 in drive 0 -- error"
--bin/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive0 0
- echo "rtn=$?"
- echo "Unload drive 0"
--bin/disk-changer tmp/disk-changer/conf unload 1 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf unload 1 tmp/disk-changer/drive0 0
- echo "rtn=$?"
- echo "Load Slot 2 in drive 0 -- should fail"
--bin/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive0 0
-+$scripts/disk-changer tmp/disk-changer/conf load 2 tmp/disk-changer/drive0 0
- echo "rtn=$?"
-Index: tests/bug-fatal-test
-===================================================================
---- tests/bug-fatal-test (révision 7994)
-+++ tests/bug-fatal-test (copie de travail)
-@@ -34,12 +34,11 @@
- END_OF_DATA
-
-
--bin/bacula start
--cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf > /dev/null
-+run_bacula
- stop_bacula
-
--export dstat=0
--export bstat=0
--export rstat=0
-+dstat=0
-+bstat=0
-+rstat=0
-
- end_test
-Index: tests/errors-test
-===================================================================
---- tests/errors-test (révision 7994)
-+++ tests/errors-test (copie de travail)
-@@ -64,7 +64,7 @@
-
- run_bacula
- touch ${cwd}/tmp/log1.out
--client=$(grep client= bin/bacula-dir.conf)
-+client=`grep client= $bin/bacula-dir.conf`
- check_for_zombie_jobs storage=File $client
- stop_bacula
-
-Index: tests/restore-by-file-tape
-===================================================================
---- tests/restore-by-file-tape (révision 7994)
-+++ tests/restore-by-file-tape (copie de travail)
-@@ -93,7 +93,7 @@
- check_two_logs
-
- scripts/check_for_zombie_jobs storage=DDS-4
--bin/bacula stop 2>&1 >/dev/null
-+stop_bacula
- for i in `cat ${cwd}/tmp/restore2-list`; do
- diff $i ${cwd}/tmp/bacula-restores$i
- if [ $? != 0 ] ; then
-Index: tests/vtape-test-changer
-===================================================================
---- tests/vtape-test-changer (révision 7994)
-+++ tests/vtape-test-changer (copie de travail)
-@@ -30,7 +30,7 @@
- when1=`perl -MPOSIX -e "print strftime('%F %T', localtime(time+30))"`
- when2=`perl -MPOSIX -e "print strftime('%F %T', localtime(time+45))"`
-
--clientname=`awk '/Name = .*-fd/ { if (!ok) { print $3 ; ok=1 } }' bin/bacula-dir.conf`
-+clientname=`awk '/Name = .*-fd/ { if (!ok) { print $3 ; ok=1 } }' $bin/bacula-dir.conf`
-
- # Catalog record for cleaning tape "CLN01" successfully created.
- # CLN01 | Cleaning
-Index: tests/usr-tape-root
-===================================================================
---- tests/usr-tape-root (révision 7994)
-+++ tests/usr-tape-root (copie de travail)
-@@ -15,8 +15,7 @@
- echo " "
- echo " "
-
--bin/bacula start 2>&1 >/dev/null
--bin/bconsole -c bin/bconsole.conf <<END_OF_DATA
-+cat <<END_OF_DATA > ${cwd}/tmp/bconcmds
- @output /dev/null
- messages
- @output tmp/log1.out
-@@ -35,7 +34,8 @@
- @output
- quit
- END_OF_DATA
--bin/bacula stop 2>&1 >/dev/null
-+run_bacula
-+stop_bacula
- cd /
- ${cwd}/bin/testls -e ${cwd}/scripts/exclude-usr-test lib >${cwd}/tmp/original
- cd ${cwd}/tmp/bacula-restores
-Index: tests/concurrent-jobs-test
-===================================================================
---- tests/concurrent-jobs-test (révision 7994)
-+++ tests/concurrent-jobs-test (copie de travail)
-@@ -16,7 +16,7 @@
- dd if=/dev/urandom of=${cwd}/tmp/largefile bs=1024 count=55000
- else
- echo "Creating a 56MB file with bacula-dir data ..."
-- dd if=bin/bacula-dir of=${cwd}/tmp/1 bs=1024 count=1000
-+ dd if=$bin/bacula-dir of=${cwd}/tmp/1 bs=1024 count=1000
- cat ${cwd}/tmp/1 ${cwd}/tmp/1 ${cwd}/tmp/1 ${cwd}/tmp/1 ${cwd}/tmp/1 >${cwd}/tmp/2
- rm -f ${cwd}/tmp/1
- cat ${cwd}/tmp/2 ${cwd}/tmp/2 ${cwd}/tmp/2 ${cwd}/tmp/2 ${cwd}/tmp/2 >>${cwd}/tmp/3
-Index: tests/accurate-test
-===================================================================
---- tests/accurate-test (révision 7994)
-+++ tests/accurate-test (copie de travail)
-@@ -157,7 +157,7 @@
- # Check with bls
- ################################################################
-
--${cwd}/bin/bls -c ${cwd}/bin/bacula-sd.conf -V 'TestVolume001' FileStorage > tmp/bls.out
-+$bin/bls -c bin/bacula-sd.conf -V 'TestVolume001' FileStorage > tmp/bls.out
- grep -- '----' tmp/bls.out | grep xxx > /dev/null
- if [ $? != 0 ] ; then
- bstat=2
-@@ -283,7 +283,7 @@
-
- bscan_libdbi
-
--${cwd}/bin/bscan -c ${cwd}/bin/bacula-sd.conf $BSCANLIBDBI -n regress -u regress -m -s -b tmp/bscan.bsr FileStorage 2>&1 > ${cwd}/tmp/bscan.log
-+$bin/bscan -c bin/bacula-sd.conf $BSCANLIBDBI -n regress -u regress -m -s -b tmp/bscan.bsr FileStorage 2>&1 > ${cwd}/tmp/bscan.log
-
- cat <<END_OF_DATA >${cwd}/tmp/bconcmds
- @$out ${cwd}/tmp/log1.out
-Index: tests/incremental-2disk
-===================================================================
---- tests/incremental-2disk (révision 7994)
-+++ tests/incremental-2disk (copie de travail)
-@@ -9,14 +9,7 @@
- JobName=Inc2disk
- . scripts/functions
-
--
--stop_bacula
--cd bin
--./drop_bacula_tables >/dev/null 2>&1
--./make_bacula_tables >/dev/null 2>&1
--./grant_bacula_privileges 2>&1 >/dev/null
--cd ..
--
-+scripts/cleanup
- scripts/copy-2disk-confs
- scripts/prepare-disk-changer
-
-Index: tests/lib-tape-root
-===================================================================
---- tests/lib-tape-root (révision 7994)
-+++ tests/lib-tape-root (copie de travail)
-@@ -5,13 +5,7 @@
- #
- cwd=`pwd`
- . scripts/functions
--bin/bacula stop 2>&1 >/dev/null
--cd bin
--./drop_bacula_tables >/dev/null 2>&1
--./make_bacula_tables >/dev/null 2>&1
--./grant_bacula_privileges 2>&1 >/dev/null
--cd ..
--
-+scripts/cleanup
- scripts/cleanup-tape
- scripts/copy-tape-confs
- echo "/lib" >${cwd}/tmp/file-list
-@@ -20,8 +14,8 @@
- echo " === Starting lib-tape-root test ==="
- echo " "
- echo " "
--bin/bacula start 2>&1 >/dev/null
--bin/bconsole -c bin/bconsole.conf <<END_OF_DATA
-+
-+cat <<END_OF_DATA > >${cwd}/tmp/bconcmds
- @output /dev/null
- messages
- @output ${cwd}/tmp/log1.out
-@@ -40,7 +34,10 @@
- @output
- quit
- END_OF_DATA
--bin/bacula stop 2>&1 >/dev/null
-+
-+run_bacula
-+stop_bacula
-+
- cd /
- ${cwd}/bin/testls -e ${cwd}/scripts/exclude-usr-test lib >${cwd}/tmp/original
- cd ${cwd}/tmp/bacula-restores
-Index: tests/two-volume-changer
-===================================================================
---- tests/two-volume-changer (révision 7994)
-+++ tests/two-volume-changer (copie de travail)
-@@ -54,7 +54,7 @@
- check_for_zombie_jobs storage=DDS-4
- stop_bacula
-
--bin/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $SLOT2 ${TAPE_DRIVE} 0
-+$scripts/${AUTOCHANGER_SCRIPT} ${AUTOCHANGER} unload $SLOT2 ${TAPE_DRIVE} 0
-
- cat <<END_OF_DATA >tmp/bconcmds
- @$out /dev/null
-Index: tests/bextract-test
-===================================================================
---- tests/bextract-test (révision 7994)
-+++ tests/bextract-test (copie de travail)
-@@ -45,9 +45,9 @@
-
- mkdir -p ${cwd}/tmp/bacula-restores
- if test "$debug" -eq 1 ; then
-- bin/bextract -v -b working/restore.bsr -c bin/bacula-sd.conf ${cwd}/tmp ${cwd}/tmp/bacula-restores
-+ $bin/bextract -v -b working/restore.bsr -c bin/bacula-sd.conf ${cwd}/tmp ${cwd}/tmp/bacula-restores
- else
-- bin/bextract -b working/restore.bsr -c bin/bacula-sd.conf ${cwd}/tmp ${cwd}/tmp/bacula-restores 2>&1 >/dev/null
-+ $bin/bextract -b working/restore.bsr -c bin/bacula-sd.conf ${cwd}/tmp ${cwd}/tmp/bacula-restores 2>&1 >/dev/null
- fi
- rstat=$?
- grep "^ Termination: *Backup OK" ${cwd}/tmp/log1.out 2>&1 >/dev/null
-Index: tests/four-jobs-tape
-===================================================================
---- tests/four-jobs-tape (révision 7994)
-+++ tests/four-jobs-tape (copie de travail)
-@@ -30,13 +30,7 @@
- messages
- quit
- END_OF_DATA
--if test "$debug" -eq 1 ; then
-- bin/bacula start
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf
--else
-- bin/bacula start 2>&1 >/dev/null
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf 2>&1 >/dev/null
--fi
-+run_bacula
-
- scripts/check_for_zombie_jobs storage=DDS-4
- echo "Backup 1 done"
-@@ -56,14 +50,9 @@
- messages
- quit
- END_OF_DATA
--if test "$debug" -eq 1 ; then
-- bin/bacula start
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf
--else
-- bin/bacula start 2>&1 >/dev/null
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf 2>&1 >/dev/null
--fi
-
-+run_bacula
-+
- scripts/check_for_zombie_jobs storage=DDS-4
- echo "Backup 2 done"
- touch ${cwd}/build/src/dird/*.c
-@@ -80,14 +69,9 @@
- messages
- quit
- END_OF_DATA
--if test "$debug" -eq 1 ; then
-- bin/bacula start
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf
--else
-- bin/bacula start 2>&1 >/dev/null
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf 2>&1 >/dev/null
--fi
-
-+run_bacula
-+
- scripts/check_for_zombie_jobs storage=DDS-4
- echo "Backup 3 done"
- # make some files for the incremental to pick up
-@@ -104,13 +88,7 @@
- messages
- quit
- END_OF_DATA
--if test "$debug" -eq 1 ; then
-- bin/bacula start
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf
--else
-- bin/bacula start 2>&1 >/dev/null
-- cat ${cwd}/tmp/bconcmds | bin/bconsole -c bin/bconsole.conf 2>&1 >/dev/null
--fi
-+run_bacula
-
- scripts/check_for_zombie_jobs storage=DDS-4
- echo "Backup 4 done"
-Index: tests/bscan-test
-===================================================================
---- tests/bscan-test (révision 7994)
-+++ tests/bscan-test (copie de travail)
-@@ -67,9 +67,9 @@
- fi
-
- if test "$debug" -eq 1 ; then
-- bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf ${cwd}/tmp
-+ $bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf ${cwd}/tmp
- else
-- bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf ${cwd}/tmp 2>&1 >tmp/log3.out
-+ $bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf ${cwd}/tmp >tmp/log3.out 2>&1
- fi
-
- cat <<END_OF_DATA >tmp/bconcmds
-Index: tests/bscan-fast-tape
-===================================================================
---- tests/bscan-fast-tape (révision 7994)
-+++ tests/bscan-fast-tape (copie de travail)
-@@ -34,7 +34,7 @@
- END_OF_DATA
-
- echo "Starting Bacula tape writing"
--#bin/btape -c bin/bacula-sd.conf /dev/nst0 <<END_OF_DATA
-+#$bin/btape -c bin/bacula-sd.conf /dev/nst0 <<END_OF_DATA
- #rewind
- #label
- #Test001
-@@ -66,7 +66,7 @@
-
- bscan_libdbi
-
--strace -o strace.new bin/bscan -d200 -w working $BSCANLIBDBI -u regress -n regress -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf DDS-4
-+strace -o strace.new $bin/bscan -d200 -w working $BSCANLIBDBI -u regress -n regress -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf DDS-4
- exit
- cat <<END_OF_DATA >tmp/bconcmds
- @$out /dev/null
-Index: tests/bscan-tape
-===================================================================
---- tests/bscan-tape (révision 7994)
-+++ tests/bscan-tape (copie de travail)
-@@ -106,9 +106,9 @@
- fi
-
- if test "$debug" -eq 1 ; then
-- bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf DDS-4
-+ $bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf DDS-4
- else
-- bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf DDS-4 2>&1 >/dev/null
-+ $bin/bscan -w working $BSCANLIBDBI -u ${db_user} -n ${db_name} $PASSWD -m -s -v -b tmp/bscan.bsr -c bin/bacula-sd.conf DDS-4 >/dev/null 2>&1
- fi
-
- echo $BSCANLIBDBI
+++ /dev/null
-Index: src/dird/ua.h
-===================================================================
---- src/dird/ua.h (revision 8163)
-+++ src/dird/ua.h (working copy)
-@@ -104,6 +104,7 @@
- JobId_t JobId;
- char ClientName[MAX_NAME_LENGTH]; /* backup client */
- char RestoreClientName[MAX_NAME_LENGTH]; /* restore client */
-+ char MediaType[MAX_NAME_LENGTH]; /* mediatype filter */
- char last_jobid[20];
- POOLMEM *JobIds; /* User entered string of JobIds */
- STORE *store;
-Index: src/dird/migrate.c
-===================================================================
---- src/dird/migrate.c (revision 8168)
-+++ src/dird/migrate.c (working copy)
-@@ -1160,13 +1160,14 @@
- * - copy any Log records to the new JobId
- */
- if (jcr->get_JobType() == JT_COPY && jcr->JobStatus == JS_Terminated) {
-- UAContext *ua = new_ua_context(jcr);
-+ Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s",
-+ (char)JT_JOBCOPY, edit_uint64(jcr->jr.JobId, ec1);
-+ db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
- /* Copy JobLog to new JobId */
- Mmsg(query, "INSERT INTO Log (JobId, Time, LogText ) "
- "SELECT %s, Time, LogText FROM Log WHERE JobId=%s",
- new_jobid, old_jobid);
- db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
-- free_ua_context(ua);
- }
-
- if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
-Index: src/dird/ua_restore.c
-===================================================================
---- src/dird/ua_restore.c (revision 8163)
-+++ src/dird/ua_restore.c (working copy)
-@@ -429,21 +429,23 @@
- "directory", /* 4 */
- "select", /* 5 */
- "pool", /* 6 */
-- "all", /* 7 */
-+ "storage", /* 7 */
-+ "mediatype", /* 8 */
-+ "all", /* 9 */
-
- /* The keyword below are handled by individual arg lookups */
-- "client", /* 8 */
-- "storage", /* 9 */
-- "fileset", /* 10 */
-- "where", /* 11 */
-- "yes", /* 12 */
-- "bootstrap", /* 13 */
-- "done", /* 14 */
-- "strip_prefix", /* 15 */
-- "add_prefix", /* 16 */
-- "add_suffix", /* 17 */
-- "regexwhere", /* 18 */
-- "restoreclient", /* 19 */
-+ "client", /* 10 */
-+ "storage", /* 11 */
-+ "fileset", /* 12 */
-+ "where", /* 13 */
-+ "yes", /* 14 */
-+ "bootstrap", /* 15 */
-+ "done", /* 16 */
-+ "strip_prefix", /* 17 */
-+ "add_prefix", /* 18 */
-+ "add_suffix", /* 19 */
-+ "regexwhere", /* 20 */
-+ "restoreclient", /* 21 */
- NULL
- };
-
-@@ -531,7 +533,24 @@
- return 0;
- }
- break;
-- case 7: /* all specified */
-+ case 7: /* storage */
-+ if (has_value(ua, i)) {
-+ rx->store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
-+ if (rx->store && !acl_access_ok(ua,Storage_ACL,rx->store->name())) {
-+ rx->store = NULL;
-+ }
-+ } else {
-+ rx->store = select_storage_resource(ua);
-+ }
-+ break;
-+ case 8: /* mediatype */
-+ if (has_value(ua, i)) {
-+ bstrncpy(rx->MediaType, ua->argv[i], sizeof(rx->MediaType));
-+ } else {
-+ ua->error_msg(_("Invalid MediaType\n"));
-+ }
-+ break;
-+ case 9: /* all specified */
- rx->all = true;
- break;
- /*
-@@ -1140,7 +1159,8 @@
- CLIENT_DBR cr;
- char fileset_name[MAX_NAME_LENGTH];
- char ed1[50], ed2[50];
-- char pool_select[MAX_NAME_LENGTH];
-+ POOL_MEM other_filter(PM_MESSAGE);
-+ POOL_MEM temp_filter(PM_MESSAGE);
- int i;
-
- /* Create temp tables */
-@@ -1196,23 +1216,43 @@
- }
-
- /* If Pool specified, add PoolId specification */
-- pool_select[0] = 0;
- if (rx->pool) {
-+ Dmsg1(0, "Use %s Pool filter\n",
-+ rx->pool->name());
- POOL_DBR pr;
- memset(&pr, 0, sizeof(pr));
- bstrncpy(pr.Name, rx->pool->name(), sizeof(pr.Name));
- if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
-- bsnprintf(pool_select, sizeof(pool_select), "AND Media.PoolId=%s ",
-- edit_int64(pr.PoolId, ed1));
-+ Mmsg(other_filter, "AND Media.PoolId=%s ",
-+ edit_int64(pr.PoolId, ed1));
- } else {
- ua->warning_msg(_("Pool \"%s\" not found, using any pool.\n"), pr.Name);
- }
- }
-+ /* use a storage filter */
-+ if (rx->store) { /* or use storageid ? */
-+ Mmsg(temp_filter, " AND Media.StorageId=%s ",
-+ edit_int64(rx->store->StorageId, ed1));
-+ pm_strcat(other_filter, temp_filter.c_str());
-+ Dmsg2(0, "Use %s StorageId filter (%s)\n",
-+ rx->store->name(), ed1);
-+ }
-+ if (rx->MediaType[0]) {
-+ Mmsg(temp_filter, " AND Media.MediaType='%s' ",
-+ rx->MediaType);
-+ pm_strcat(other_filter, temp_filter.c_str());
-+ Dmsg1(0, "Use mediatype filter (%s)\n", rx->MediaType);
-+ }
-+ if (bstrcmp(other_filter.c_str(), "")) {
-+ Dmsg0(0, "Don't use copy jobs\n");
-+ pm_strcpy(other_filter, " AND Type='B' ");
-+ }
-
- /* Find JobId of last Full backup for this client, fileset */
- edit_int64(cr.ClientId, ed1);
- Mmsg(rx->query, uar_last_full, ed1, ed1, date, fsr.FileSet,
-- pool_select);
-+ other_filter.c_str());
-+ Dmsg1(0, "q=%s\n", rx->query);
- if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
- ua->error_msg("%s\n", db_strerror(ua->db));
- goto bail_out;
-@@ -1238,7 +1278,7 @@
-
- /* Now find most recent Differental Job after Full save, if any */
- Mmsg(rx->query, uar_dif, edit_uint64(rx->JobTDate, ed1), date,
-- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
-+ edit_int64(cr.ClientId, ed2), fsr.FileSet, other_filter.c_str());
- if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
- ua->warning_msg("%s\n", db_strerror(ua->db));
- }
-@@ -1254,7 +1294,7 @@
-
- /* Now find all Incremental Jobs after Full/dif save */
- Mmsg(rx->query, uar_inc, edit_uint64(rx->JobTDate, ed1), date,
-- edit_int64(cr.ClientId, ed2), fsr.FileSet, pool_select);
-+ edit_int64(cr.ClientId, ed2), fsr.FileSet, other_filter.c_str());
- if (!db_sql_query(ua->db, rx->query, NULL, NULL)) {
- ua->warning_msg("%s\n", db_strerror(ua->db));
- }
-Index: src/jcr.h
-===================================================================
---- src/jcr.h (revision 8163)
-+++ src/jcr.h (working copy)
-@@ -65,6 +65,7 @@
- #define JT_ADMIN 'D' /* admin job */
- #define JT_ARCHIVE 'A' /* Archive Job */
- #define JT_COPY 'C' /* Copy Job */
-+#define JT_JOBCOPY 'J' /* Copy Job */
- #define JT_MIGRATE 'g' /* Migration Job */
- #define JT_SCAN 'S' /* Scan Job */
-
-Index: src/lib/util.c
-===================================================================
---- src/lib/util.c (revision 8163)
-+++ src/lib/util.c (working copy)
-@@ -361,6 +361,9 @@
- case JT_COPY:
- str = _("Copy");
- break;
-+ case JT_JOBCOPY:
-+ str = _("Job Copy");
-+ break;
- case JT_CONSOLE:
- str = _("Console");
- break;
+++ /dev/null
-#include "bacula.h"
-#include "bregex.h"
-
-/* s/toto(.)/titi$1/
- * toto est beau => titi est beau
- *
- */
-
-/* re_match()
- * compute_dest_len()
- * check_pool_size()
- * edit()
- */
-
-typedef struct {
- char *subst;
- char *motif;
- int nmatch;
- regex_t preg;
-} breg_t ;
-
-breg_t *breg_new(char *regexp)
-{
- Dmsg0(500, "breg: creating new breg_t object\n");
- RUNSCRIPT *cmd = (RUNSCRIPT *)malloc(sizeof(RUNSCRIPT));
- memset(cmd, 0, sizeof(RUNSCRIPT));
- cmd->reset_default();
-
- return cmd;
-
-}
-
-
-int compute_dest_len(char *fname, char *subst,
- regmatch_t *pmatch, int nmatch)
-{
- int len=0;
- char *p;
- int no;
-
- if (!fname || !subst || !pmatch || !nmatch) {
- return 0;
- }
-
- /* match failed ? */
- if (pmatch[0].rm_so < 0) {
- return 0;
- }
-
- for (p = subst++; *p ; p = subst++) {
- /* match $1 \1 back references */
- if ((*p == '$' || *p == '\\') && ('0' <= *subst && *subst <= '9')) {
- no = *subst++ - '0';
-
- /* we check if the back reference exists */
- if (no < nmatch && pmatch[no].rm_so >= 0 && pmatch[no].rm_eo >= 0) {
- len += pmatch[no].rm_eo - pmatch[no].rm_so;
- } else {
- return 0; /* back reference missing or reference number > nmatch */
- }
- } else {
- len++;
- }
- }
-
- /* $0 is replaced by subst */
- len -= pmatch[0].rm_eo - pmatch[0].rm_so;
- len += strlen(fname) + 1;
-
- return len;
-}
-
-/* /toto/titi/
- * preg
- * subst
- */
-bool extract_regexp(char *motif, regex_t *preg, POOLMEM **subst)
-{
- if (!motif || !preg || !subst) {
- return false;
- }
- /* extract 1st part */
- POOLMEM *dest = bstrdup(motif);
- char sep = motif[0];
- char *search = motif + 1;
- char *replace;
- bool ok = false;
- bool found_motif = false;
-
- while (*search && !ok) {
- if (*search == sep && *dest == '\\') {
- *dest++ = *++search; /* we skip separator */
-
- } else if (*search == sep) {
- *dest++ = '\0';
- if (found_motif) { /* already have found motif */
- ok = true;
- } else {
- replace = dest; /* get replaced string */
- found_motif = true;
- }
- } else {
- *dest++ = *search++;
- }
- }
- *dest = '\0'; /* in case of */
-
- if (!ok || !found_motif) {
- /* bad regexp */
- free(dest);
- return false;
- }
-
-
-
-
- /* rechercher le 1er car sans \ devant */
- /* compiler la re dans preg */
- /* extraire le subst */
- /* verifier le nombre de reference */
-}
-
-/* dest is long enough */
-char *edit_subst(char *fname, char *subst, regmatch_t *pmatch, char *dest)
-{
- int i;
- char *p;
- int no;
- int len;
-
- /* il faut recopier fname dans dest
- * on recopie le debut fname -> pmatch[0].rm_so
- */
-
- for (i = 0; i < pmatch[0].rm_so ; i++) {
- dest[i] = fname[i];
- }
-
- /* on recopie le motif de remplacement (avec tous les $x) */
-
- for (p = subst++; *p ; p = subst++) {
- /* match $1 \1 back references */
- if ((*p == '$' || *p == '\\') && ('0' <= *subst && *subst <= '9')) {
- no = *subst++ - '0';
-
- len = pmatch[no].rm_eo - pmatch[no].rm_so;
- bstrncpy(dest + i, fname + pmatch[no].rm_so, len);
- i += len;
-
- } else {
- dest[i++] = *p;
- }
- }
-
- strcpy(dest + i, fname + pmatch[0].rm_eo);
-
- return dest;
-}
-
-/* return jcr->subst_fname or fname */
-char *fname_subst(JCR *jcr, char *fname)
-{
- /* in JCR */
- regex_t preg;
- char *pat="$";
- char *subst=".old";
- char *dest=NULL;
-
- int rc = regcomp(&preg, pat, REG_EXTENDED);
- if (rc != 0) {
- char prbuf[500];
- regerror(rc, &preg, prbuf, sizeof(prbuf));
- printf("Regex compile error: %s\n", prbuf);
- return fname;
- }
-
- const int nmatch = 30;
- regmatch_t pmatch[nmatch];
- rc = regexec(&preg, fname, nmatch, pmatch, 0);
-
- if (!rc) {
- char prbuf[500];
- regerror(rc, &preg, prbuf, sizeof(prbuf));
- printf("Regex error: %s\n", prbuf);
- return fname;
- }
-
- int len = compute_dest_len(fname, subst,
- pmatch, nmatch);
-
- if (len) {
- dest = (char *)malloc(len);
- edit_subst(fname, subst, pmatch, dest);
- }
-
- return dest;
-}
+++ /dev/null
-#include <sys/mtio.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#ifndef FTAPE
-#include "faketape.h"
-
-#define write faketape_write
-#define open faketape_open
-#define read faketape_read
-#define close faketape_close
-#define ioctl faketape_ioctl
-#define debug(x) faketape_debug(x)
-#else
-#define debug(x)
-#endif
-
-static int fd;
-void print_pos()
-{
- struct mtget mt_get;
- ioctl(fd, MTIOCGET, &mt_get);
- printf("*** file:block %i:%i BOT=%u EOD=%u EOF=%u\n",
- mt_get.mt_fileno, mt_get.mt_blkno,
- GMT_BOT(mt_get.mt_gstat) != 0,
- GMT_EOD(mt_get.mt_gstat) != 0,
- GMT_EOF(mt_get.mt_gstat) != 0
- );
-}
-
-int main(int argc, char **argv)
-{
- int r1;
- char c[200];
- struct mtop mt_com;
-
- if (argc > 1) {
- debug(atoi(argv[1]));
- }
-
- fd = open("/dev/lto2", O_CREAT | O_RDWR);
- if (fd < 0) {
- perror("Can't open fd");
- exit(1);
- }
-
- print_pos();
-
- /* rewind */
- printf("\n*** rewind\n");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTREW;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
-
- exit(0);
-
- /* write something */
- printf("\n*** write something (3 writes)\n");
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- print_pos();
-
- /* write EOF */
- printf("\n*** WEOF\n");
- mt_com.mt_op = MTWEOF;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- print_pos();
-
- write(fd, "12345", strlen("12345")+1);
- write(fd, "678910", strlen("678910")+1);
-
- /* write EOF */
- printf("\n*** WEOF\n");
- mt_com.mt_op = MTWEOF;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- print_pos();
-
-
-
- /* BSF */
- printf("\n*** bsf\n");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTBSF;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- print_pos();
-
- /* BSR */
- printf("\n*** bsr\n");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTBSR;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
-
- /* read something */
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- printf("\n*** read c=%s len=%i\n", c, r1);
- print_pos();
- exit(0);
-
- /* FSR */
- printf("\n*** fsr");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
- /* FSR */
- printf("\n*** fsr");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
- /* FSR */
- printf("\n*** fsr");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
- /* FSR */
- printf("\n*** fsr");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
- /* FSR */
- printf("\n*** fsr");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
- exit(0);
-
-
- /* write a second file */
- printf("\n*** write something\n");
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- print_pos();
-
- /* BSF */
- printf("\n*** bsf\n");
- mt_com.mt_op = MTBSF;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- print_pos();
-
- /* rewind */
- printf("\n*** rewind\n");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTREW;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
-
- /* read something with error */
- printf("\n*** read c=%s len=%i\n", c, r1);
- errno=0;
- r1 = read(fd, c, 2);
- c[r1] = 0;
- perror("");
- print_pos();
-
- /* read something */
- printf("\n*** read c=%s len=%i\n", c, r1);
- errno=0;
- r1 = read(fd, c, 200);
- c[r1] = 0;
- print_pos();
-
- /* write something */
- printf("\n*** write something\n");
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- print_pos();
-
- /* rewind */
- printf("\n*** rewind\n");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTREW;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- r1 = read(fd, c, 200);
- c[r1] = '\0';
- printf("\n*** read c=%s len=%i\n", c, r1);
- r1 = read(fd, c, 200);
- c[r1] = '\0';
- printf("\n*** read c=%s len=%i\n", c, r1);
-
- /* write EOF */
- printf("\n*** WEOF");
- mt_com.mt_op = MTWEOF;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* FSF */
- printf("\n*** fsf x1");
- mt_com.mt_op = MTFSF;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* write something */
- printf("\n*** write something\n");
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- print_pos();
-
- /* FSF */
- printf("\n*** fsf");
- mt_com.mt_op = MTFSF;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* WEOF */
- printf("\n*** weof 3");
- mt_com.mt_op = MTWEOF;
- mt_com.mt_count = 3;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* rewind */
- printf("\n*** rewind\n");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTREW;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- print_pos();
-
- /* FSR */
- printf("\n*** fsr x10");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 10;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* eom */
- printf("\n*** goto eom");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTEOM;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* fsr */
- printf("\n*** fsr");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTFSR;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* write something */
- printf("\n*** write something\n");
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- print_pos();
-
- /* rewind */
- printf("\n*** rewind");
- mt_com.mt_count = 1;
- mt_com.mt_op = MTREW;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
-
- /* FSF */
- printf("\n*** fsf x2");
- mt_com.mt_op = MTFSF;
- mt_com.mt_count = 2;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- printf("\n*** fsr");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- /* write something */
- printf("\n*** write something\n");
- write(fd, "abcdefghijklmnopqrstuvwyz", strlen("abcdefghijklmnopqrstuvwyz")+1);
- print_pos();
-
- printf("\n*** bsf x2");
- mt_com.mt_op = MTBSF;
- mt_com.mt_count = 2;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- printf("\n*** bsf x10");
- mt_com.mt_op = MTBSF;
- mt_com.mt_count = 10;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- printf("\n*** eom");
- mt_com.mt_op = MTEOM;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- printf("\n*** bsr x10");
- mt_com.mt_op = MTBSR;
- mt_com.mt_count = 10;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- printf("\n*** eom");
- mt_com.mt_op = MTEOM;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- printf("\n*** fsr");
- mt_com.mt_op = MTFSR;
- mt_com.mt_count = 1;
- r1 = ioctl(fd, MTIOCTOP, &mt_com);
- printf(" r=%i\n", r1);
- print_pos();
-
- close(fd);
- return(0);
-}