--- /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);