]> git.sur5r.net Git - bacula/bacula/commitdiff
Add old 1.36.1 patches in new directory
authorKern Sibbald <kern@sibbald.com>
Sun, 6 Mar 2005 13:45:35 +0000 (13:45 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 6 Mar 2005 13:45:35 +0000 (13:45 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1866 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/patches/1.36.1/1.36.1-acl.patch [new file with mode: 0644]
bacula/patches/1.36.1/1.36.1-fileset.patch [new file with mode: 0644]
bacula/patches/1.36.1/1.36.1-pool.patch [new file with mode: 0644]
bacula/patches/1.36.1/1.36.1-reload.patch [new file with mode: 0644]
bacula/patches/1.36.1/1.36.1-slots.patch [new file with mode: 0644]
bacula/patches/1.36.1/1.36.1-spool.patch [new file with mode: 0644]
bacula/patches/1.36.1/1.36.1-store.patch [new file with mode: 0644]
bacula/patches/1.36.1/1.36.1-truncate.patch [new file with mode: 0644]
bacula/patches/1.36.1/patches-1.36.1 [new file with mode: 0644]

diff --git a/bacula/patches/1.36.1/1.36.1-acl.patch b/bacula/patches/1.36.1/1.36.1-acl.patch
new file mode 100644 (file)
index 0000000..3c0b907
--- /dev/null
@@ -0,0 +1,70 @@
+
+ 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) {
diff --git a/bacula/patches/1.36.1/1.36.1-fileset.patch b/bacula/patches/1.36.1/1.36.1-fileset.patch
new file mode 100644 (file)
index 0000000..99104c1
--- /dev/null
@@ -0,0 +1,160 @@
+
+ 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);
diff --git a/bacula/patches/1.36.1/1.36.1-pool.patch b/bacula/patches/1.36.1/1.36.1-pool.patch
new file mode 100644 (file)
index 0000000..bbe1a00
--- /dev/null
@@ -0,0 +1,152 @@
+
+ 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()
diff --git a/bacula/patches/1.36.1/1.36.1-reload.patch b/bacula/patches/1.36.1/1.36.1-reload.patch
new file mode 100644 (file)
index 0000000..022ee33
--- /dev/null
@@ -0,0 +1,50 @@
+ 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);
diff --git a/bacula/patches/1.36.1/1.36.1-slots.patch b/bacula/patches/1.36.1/1.36.1-slots.patch
new file mode 100644 (file)
index 0000000..7042082
--- /dev/null
@@ -0,0 +1,28 @@
+
+ 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);
+    }
diff --git a/bacula/patches/1.36.1/1.36.1-spool.patch b/bacula/patches/1.36.1/1.36.1-spool.patch
new file mode 100644 (file)
index 0000000..899d755
--- /dev/null
@@ -0,0 +1,28 @@
+
+ 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; 
diff --git a/bacula/patches/1.36.1/1.36.1-store.patch b/bacula/patches/1.36.1/1.36.1-store.patch
new file mode 100644 (file)
index 0000000..8b0a926
--- /dev/null
@@ -0,0 +1,802 @@
+ 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);
diff --git a/bacula/patches/1.36.1/1.36.1-truncate.patch b/bacula/patches/1.36.1/1.36.1-truncate.patch
new file mode 100644 (file)
index 0000000..a66a1e5
--- /dev/null
@@ -0,0 +1,24 @@
+
+ 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;
+    }   
diff --git a/bacula/patches/1.36.1/patches-1.36.1 b/bacula/patches/1.36.1/patches-1.36.1
new file mode 100644 (file)
index 0000000..1a41d7c
--- /dev/null
@@ -0,0 +1,40 @@
+
+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.