2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- Run Command
32 * Kern Sibbald, December MMI
42 char *job_name, *level_name, *jid, *store_name, *pool_name;
43 char *where, *fileset_name, *client_name, *bootstrap, *regexwhere;
44 char *restore_client_name;
46 char *when, *verify_job_name, *catalog_name;
47 char *previous_job_name;
49 const char *verify_list;
64 run_ctx() { memset(this, 0, sizeof(run_ctx));
65 store = new USTORE; };
66 ~run_ctx() { delete store; };
69 /* Forward referenced subroutines */
70 static void select_job_level(UAContext *ua, JCR *jcr);
71 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job,
72 const char *verify_list, char *jid, const char *replace,
74 static void select_where_regexp(UAContext *ua, JCR *jcr);
75 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc);
77 /* Imported variables */
78 extern struct s_kw ReplaceOptions[];
81 * For Backup and Verify Jobs
82 * run [job=]<job-name> level=<level-name>
91 int run_cmd(UAContext *ua, const char *cmd)
97 if (!open_client_db(ua)) {
101 if (!scan_command_line_arguments(ua, rc)) {
105 if (find_arg(ua, NT_("fdcalled")) > 0) {
106 jcr->file_bsock = dup_bsock(ua->UA_sock);
112 * Create JCR to run job. NOTE!!! after this point, free_jcr()
116 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
117 set_jcr_defaults(jcr, rc.job);
118 jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */
119 ua->jcr->unlink_bsr = false;
122 jcr->verify_job = rc.verify_job;
123 jcr->previous_job = rc.previous_job;
125 set_rwstorage(jcr, rc.store);
126 jcr->client = rc.client;
127 pm_strcpy(jcr->client_name, rc.client->name());
128 jcr->fileset = rc.fileset;
129 jcr->ExpectedFiles = rc.files;
131 jcr->catalog = rc.catalog;
137 jcr->where = bstrdup(rc.where);
142 if (jcr->RegexWhere) {
143 free(jcr->RegexWhere);
145 jcr->RegexWhere = bstrdup(rc.regexwhere);
146 rc.regexwhere = NULL;
150 jcr->sched_time = str_to_utime(rc.when);
151 if (jcr->sched_time == 0) {
152 ua->send_msg(_("Invalid time, using current time.\n"));
153 jcr->sched_time = time(NULL);
159 if (jcr->RestoreBootstrap) {
160 free(jcr->RestoreBootstrap);
162 jcr->RestoreBootstrap = bstrdup(rc.bootstrap);
168 for (i=0; ReplaceOptions[i].name; i++) {
169 if (strcasecmp(rc.replace, ReplaceOptions[i].name) == 0) {
170 jcr->replace = ReplaceOptions[i].token;
174 ua->send_msg(_("Invalid replace option: %s\n"), rc.replace);
177 } else if (rc.job->replace) {
178 jcr->replace = rc.job->replace;
180 jcr->replace = REPLACE_ALWAYS;
185 jcr->JobPriority = rc.Priority;
191 jcr->stime = get_pool_memory(PM_MESSAGE);
193 pm_strcpy(jcr->stime, rc.since);
198 jcr->cloned = rc.cloned;
203 /* If pool changed, update migration write storage */
204 if (jcr->JobType == JT_MIGRATE) {
205 if (!set_migration_wstorage(jcr, rc.pool)) {
209 rc.replace = ReplaceOptions[0].name;
210 for (i=0; ReplaceOptions[i].name; i++) {
211 if (ReplaceOptions[i].token == jcr->replace) {
212 rc.replace = ReplaceOptions[i].name;
216 if (!get_level_from_name(jcr, rc.level_name)) {
217 ua->send_msg(_("Level %s not valid.\n"), rc.level_name);
220 rc.level_name = NULL;
223 /* Note, this is also MigrateJobId */
224 jcr->RestoreJobId = str_to_int64(rc.jid);
228 /* Run without prompting? */
229 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
234 * Prompt User to see if all run job parameters are correct, and
235 * allow him to modify them.
237 if (!display_job_parameters(ua, jcr, rc.job, rc.verify_list, rc.jid, rc.replace,
242 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
246 if (strncasecmp(ua->cmd, ".mod ", 5) == 0 ||
247 (strncasecmp(ua->cmd, "mod ", 4) == 0 && strlen(ua->cmd) > 6)) {
250 if (!scan_command_line_arguments(ua, rc)) {
257 * At user request modify parameters of job to be run.
259 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
262 start_prompt(ua, _("Parameters to modify:\n"));
263 add_prompt(ua, _("Level")); /* 0 */
264 add_prompt(ua, _("Storage")); /* 1 */
265 add_prompt(ua, _("Job")); /* 2 */
266 add_prompt(ua, _("FileSet")); /* 3 */
267 if (jcr->JobType == JT_RESTORE) {
268 add_prompt(ua, _("Restore Client")); /* 4 */
270 add_prompt(ua, _("Client")); /* 4 */
272 add_prompt(ua, _("When")); /* 5 */
273 add_prompt(ua, _("Priority")); /* 6 */
274 if (jcr->JobType == JT_BACKUP ||
275 jcr->JobType == JT_MIGRATE ||
276 jcr->JobType == JT_VERIFY) {
277 add_prompt(ua, _("Pool")); /* 7 */
278 if (jcr->JobType == JT_VERIFY) {
279 add_prompt(ua, _("Verify Job")); /* 8 */
281 } else if (jcr->JobType == JT_RESTORE) {
282 add_prompt(ua, _("Bootstrap")); /* 7 */
283 add_prompt(ua, _("Where")); /* 8 */
284 add_prompt(ua, _("File Relocation"));/* 9 */
285 add_prompt(ua, _("Replace")); /* 10 */
286 add_prompt(ua, _("JobId")); /* 11 */
288 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
291 select_job_level(ua, jcr);
295 rc.store->store = select_storage_resource(ua);
296 if (rc.store->store) {
297 pm_strcpy(rc.store->store_source, _("user selection"));
298 set_rwstorage(jcr, rc.store);
304 rc.job = select_job_resource(ua);
307 set_jcr_defaults(jcr, rc.job);
313 rc.fileset = select_fileset_resource(ua);
315 jcr->fileset = rc.fileset;
321 rc.client = select_client_resource(ua);
323 jcr->client = rc.client;
329 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
332 if (ua->cmd[0] == 0) {
333 jcr->sched_time = time(NULL);
335 jcr->sched_time = str_to_utime(ua->cmd);
336 if (jcr->sched_time == 0) {
337 ua->send_msg(_("Invalid time, using current time.\n"));
338 jcr->sched_time = time(NULL);
344 if (!get_pint(ua, _("Enter new Priority: "))) {
347 if (ua->pint32_val == 0) {
348 ua->send_msg(_("Priority must be a positive integer.\n"));
350 jcr->JobPriority = ua->pint32_val;
354 /* Pool or Bootstrap depending on JobType */
355 if (jcr->JobType == JT_BACKUP ||
356 jcr->JobType == JT_MIGRATE ||
357 jcr->JobType == JT_VERIFY) { /* Pool */
358 rc.pool = select_pool_resource(ua);
361 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
368 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
371 if (jcr->RestoreBootstrap) {
372 free(jcr->RestoreBootstrap);
373 jcr->RestoreBootstrap = NULL;
375 if (ua->cmd[0] != 0) {
376 jcr->RestoreBootstrap = bstrdup(ua->cmd);
377 fd = fopen(jcr->RestoreBootstrap, "rb");
380 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
381 jcr->RestoreBootstrap, be.bstrerror());
382 free(jcr->RestoreBootstrap);
383 jcr->RestoreBootstrap = NULL;
391 if (jcr->JobType == JT_VERIFY) {
392 rc.verify_job = select_job_resource(ua);
394 jcr->verify_job = rc.verify_job;
399 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
402 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
403 free(jcr->RegexWhere);
404 jcr->RegexWhere = NULL;
410 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
413 jcr->where = bstrdup(ua->cmd);
416 /* File relocation */
417 select_where_regexp(ua, jcr);
421 start_prompt(ua, _("Replace:\n"));
422 for (i=0; ReplaceOptions[i].name; i++) {
423 add_prompt(ua, ReplaceOptions[i].name);
425 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
427 jcr->replace = ReplaceOptions[opt].token;
432 rc.jid = NULL; /* force reprompt */
433 jcr->RestoreJobId = 0;
434 if (jcr->RestoreBootstrap) {
435 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
438 case -1: /* error or cancel */
446 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
448 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
451 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
452 JobId = run_job(jcr);
453 free_jcr(jcr); /* release jcr */
455 ua->error_msg(_("Job failed.\n"));
458 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
464 ua->send_msg(_("Job not run.\n"));
466 return 0; /* do not run */
469 static void select_where_regexp(UAContext *ua, JCR *jcr)
472 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
473 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
476 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
477 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
479 start_prompt(ua, _("This will replace your current Where value\n"));
480 add_prompt(ua, _("Strip prefix")); /* 0 */
481 add_prompt(ua, _("Add prefix")); /* 1 */
482 add_prompt(ua, _("Add file suffix")); /* 2 */
483 add_prompt(ua, _("Enter a regexp")); /* 3 */
484 add_prompt(ua, _("Test filename manipulation")); /* 4 */
485 add_prompt(ua, _("Use this ?")); /* 5 */
487 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
490 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
491 if (strip_prefix) bfree(strip_prefix);
492 strip_prefix = bstrdup(ua->cmd);
498 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
499 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
503 if (add_prefix) bfree(add_prefix);
504 add_prefix = bstrdup(ua->cmd);
509 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
510 if (add_suffix) bfree(add_suffix);
511 add_suffix = bstrdup(ua->cmd);
516 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
517 if (rwhere) bfree(rwhere);
518 rwhere = bstrdup(ua->cmd);
527 if (rwhere && rwhere[0] != '\0') {
528 regs = get_bregexps(rwhere);
529 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
531 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
532 regexp = (char *) bmalloc (len * sizeof(char));
533 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
534 regs = get_bregexps(regexp);
535 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
536 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
542 ua->send_msg(_("Cannot use your regexp\n"));
546 while (get_cmd(ua, _("Please enter filename to test: "))) {
547 apply_bregexps(ua->cmd, regs, &result);
548 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
557 case -1: /* error or cancel */
563 /* replace the existing where */
569 /* replace the existing regexwhere */
570 if (jcr->RegexWhere) {
571 bfree(jcr->RegexWhere);
572 jcr->RegexWhere = NULL;
576 jcr->RegexWhere = bstrdup(rwhere);
577 } else if (strip_prefix || add_prefix || add_suffix) {
578 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
579 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
580 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
583 regs = get_bregexps(jcr->RegexWhere);
588 if (jcr->RegexWhere) {
589 bfree(jcr->RegexWhere);
590 jcr->RegexWhere = NULL;
592 ua->send_msg(_("Cannot use your regexp.\n"));
596 if (strip_prefix) bfree(strip_prefix);
597 if (add_prefix) bfree(add_prefix);
598 if (add_suffix) bfree(add_suffix);
599 if (rwhere) bfree(rwhere);
602 static void select_job_level(UAContext *ua, JCR *jcr)
604 if (jcr->JobType == JT_BACKUP) {
605 start_prompt(ua, _("Levels:\n"));
606 add_prompt(ua, _("Base"));
607 add_prompt(ua, _("Full"));
608 add_prompt(ua, _("Incremental"));
609 add_prompt(ua, _("Differential"));
610 add_prompt(ua, _("Since"));
611 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
613 jcr->JobLevel = L_BASE;
616 jcr->JobLevel = L_FULL;
619 jcr->JobLevel = L_INCREMENTAL;
622 jcr->JobLevel = L_DIFFERENTIAL;
625 jcr->JobLevel = L_SINCE;
630 } else if (jcr->JobType == JT_VERIFY) {
631 start_prompt(ua, _("Levels:\n"));
632 add_prompt(ua, _("Initialize Catalog"));
633 add_prompt(ua, _("Verify Catalog"));
634 add_prompt(ua, _("Verify Volume to Catalog"));
635 add_prompt(ua, _("Verify Disk to Catalog"));
636 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
637 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
639 jcr->JobLevel = L_VERIFY_INIT;
642 jcr->JobLevel = L_VERIFY_CATALOG;
645 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
648 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
651 jcr->JobLevel = L_VERIFY_DATA;
657 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
662 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, const char *verify_list,
663 char *jid, const char *replace, char *client_name)
665 Dmsg1(800, "JobType=%c\n", jcr->JobType);
666 switch (jcr->JobType) {
668 char dt[MAX_TIME_LENGTH];
670 if (ua->api) ua->signal(BNET_RUN_CMD);
671 ua->send_msg(_("Run %s job\n"
680 jcr->fileset->name(),
681 NPRT(jcr->client->name()),
682 jcr->wstore?jcr->wstore->name():"*None*",
683 bstrutime(dt, sizeof(dt), jcr->sched_time),
685 jcr->JobLevel = L_FULL;
689 if (jcr->JobType == JT_BACKUP) {
690 if (ua->api) ua->signal(BNET_RUN_CMD);
691 ua->send_msg(_("Run %s job\n"
696 "Pool: %s (From %s)\n"
697 "Storage: %s (From %s)\n"
702 level_to_str(jcr->JobLevel),
704 jcr->fileset->name(),
705 NPRT(jcr->pool->name()), jcr->pool_source,
706 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
707 bstrutime(dt, sizeof(dt), jcr->sched_time),
709 } else { /* JT_VERIFY */
711 if (jcr->verify_job) {
712 Name = jcr->verify_job->name();
717 verify_list = job->WriteVerifyList;
722 if (ua->api) ua->signal(BNET_RUN_CMD);
723 ua->send_msg(_("Run %s job\n"
728 "Pool: %s (From %s)\n"
729 "Storage: %s (From %s)\n"
736 level_to_str(jcr->JobLevel),
738 jcr->fileset->name(),
739 NPRT(jcr->pool->name()), jcr->pool_source,
740 jcr->rstore->name(), jcr->rstore_source,
743 bstrutime(dt, sizeof(dt), jcr->sched_time),
748 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
750 jcr->RestoreJobId = str_to_int64(jid);
752 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
755 jcr->RestoreJobId = ua->int64_val;
758 jcr->JobLevel = L_FULL; /* default level */
759 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
760 if (jcr->RestoreJobId == 0) {
761 if (ua->api) ua->signal(BNET_RUN_CMD);
762 /* RegexWhere is take before RestoreWhere */
763 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
764 ua->send_msg(_("Run Restore job\n"
770 "Backup Client: %s\n"
771 "Restore Client: %s\n"
777 NPRT(jcr->RestoreBootstrap),
778 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
780 jcr->fileset->name(),
784 bstrutime(dt, sizeof(dt), jcr->sched_time),
785 jcr->catalog->name(),
789 ua->send_msg(_("Run Restore job\n"
795 "Backup Client: %s\n"
796 "Restore Client: %s\n"
802 NPRT(jcr->RestoreBootstrap),
803 jcr->where?jcr->where:NPRT(job->RestoreWhere),
805 jcr->fileset->name(),
809 bstrutime(dt, sizeof(dt), jcr->sched_time),
810 jcr->catalog->name(),
815 if (ua->api) ua->signal(BNET_RUN_CMD);
816 ua->send_msg(_("Run Restore job\n"
820 NPRT(jcr->RestoreBootstrap));
822 /* RegexWhere is take before RestoreWhere */
823 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
824 ua->send_msg(_("RegexWhere: %s\n"),
825 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
827 ua->send_msg(_("Where: %s\n"),
828 jcr->where?jcr->where:NPRT(job->RestoreWhere));
831 ua->send_msg(_("Replace: %s\n"
841 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
842 bstrutime(dt, sizeof(dt), jcr->sched_time),
843 jcr->catalog->name(),
848 jcr->JobLevel = L_FULL; /* default level */
849 if (ua->api) ua->signal(BNET_RUN_CMD);
850 ua->send_msg(_("Run Migration job\n"
855 "Pool: %s (From %s)\n"
856 "Read Storage: %s (From %s)\n"
857 "Write Storage: %s (From %s)\n"
863 NPRT(jcr->RestoreBootstrap),
865 jcr->fileset->name(),
866 NPRT(jcr->pool->name()), jcr->pool_source,
867 jcr->rstore->name(), jcr->rstore_source,
868 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
869 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
870 bstrutime(dt, sizeof(dt), jcr->sched_time),
871 jcr->catalog->name(),
875 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
882 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
886 static const char *kw[] = { /* command line arguments */
887 "job", /* Used in a switch() */
895 "regexwhere", /* 8 where string as a bregexp */
897 "bootstrap", /* 10 */
901 "yes", /* 14 -- if you change this change YES_POS too */
902 "verifyjob", /* 15 */
903 "files", /* 16 number of files to restore */
904 "catalog", /* 17 override catalog */
905 "since", /* 18 since */
906 "cloned", /* 19 cloned */
907 "verifylist", /* 20 verify output list */
908 "migrationjob", /* 21 migration job name */
910 "backupclient", /* 23 */
911 "restoreclient", /* 24 */
916 rc.catalog_name = NULL;
919 rc.store_name = NULL;
920 rc.client_name = NULL;
921 rc.restore_client_name = NULL;
922 rc.fileset_name = NULL;
923 rc.verify_job_name = NULL;
924 rc.previous_job_name = NULL;
927 for (i=1; i<ua->argc; i++) {
928 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
930 /* Keep looking until we find a good keyword */
931 for (j=0; !kw_ok && kw[j]; j++) {
932 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
933 /* Note, yes and run have no value, so do not fail */
934 if (!ua->argv[i] && j != YES_POS /*yes*/) {
935 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
938 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
942 ua->send_msg(_("Job name specified twice.\n"));
945 rc.job_name = ua->argv[i];
949 if (rc.jid && !rc.mod) {
950 ua->send_msg(_("JobId specified twice.\n"));
953 rc.jid = ua->argv[i];
958 if (rc.client_name) {
959 ua->send_msg(_("Client specified twice.\n"));
962 rc.client_name = ua->argv[i];
965 case 4: /* fileset */
966 if (rc.fileset_name) {
967 ua->send_msg(_("FileSet specified twice.\n"));
970 rc.fileset_name = ua->argv[i];
975 ua->send_msg(_("Level specified twice.\n"));
978 rc.level_name = ua->argv[i];
981 case 6: /* storage */
984 ua->send_msg(_("Storage specified twice.\n"));
987 rc.store_name = ua->argv[i];
990 case 8: /* regexwhere */
991 if ((rc.regexwhere || rc.where) && !rc.mod) {
992 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
995 rc.regexwhere = ua->argv[i];
996 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
997 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
1003 if ((rc.where || rc.regexwhere) && !rc.mod) {
1004 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
1007 rc.where = ua->argv[i];
1008 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
1009 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
1014 case 10: /* bootstrap */
1015 if (rc.bootstrap && !rc.mod) {
1016 ua->send_msg(_("Bootstrap specified twice.\n"));
1019 rc.bootstrap = ua->argv[i];
1022 case 11: /* replace */
1023 if (rc.replace && !rc.mod) {
1024 ua->send_msg(_("Replace specified twice.\n"));
1027 rc.replace = ua->argv[i];
1031 if (rc.when && !rc.mod) {
1032 ua->send_msg(_("When specified twice.\n"));
1035 rc.when = ua->argv[i];
1038 case 13: /* Priority */
1039 if (rc.Priority && !rc.mod) {
1040 ua->send_msg(_("Priority specified twice.\n"));
1043 rc.Priority = atoi(ua->argv[i]);
1044 if (rc.Priority <= 0) {
1045 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1053 case 15: /* Verify Job */
1054 if (rc.verify_job_name) {
1055 ua->send_msg(_("Verify Job specified twice.\n"));
1058 rc.verify_job_name = ua->argv[i];
1061 case 16: /* files */
1062 rc.files = atoi(ua->argv[i]);
1066 case 17: /* catalog */
1067 rc.catalog_name = ua->argv[i];
1071 case 18: /* since */
1072 rc.since = ua->argv[i];
1076 case 19: /* cloned */
1081 case 20: /* write verify list output */
1082 rc.verify_list = ua->argv[i];
1085 case 21: /* Migration Job */
1086 if (rc.previous_job_name) {
1087 ua->send_msg(_("Migration Job specified twice.\n"));
1090 rc.previous_job_name = ua->argv[i];
1095 ua->send_msg(_("Pool specified twice.\n"));
1098 rc.pool_name = ua->argv[i];
1101 case 23: /* backupclient */
1102 if (rc.client_name) {
1103 ua->send_msg(_("Client specified twice.\n"));
1106 rc.client_name = ua->argv[i];
1109 case 24: /* restoreclient */
1110 if (rc.restore_client_name && !rc.mod) {
1111 ua->send_msg(_("Restore Client specified twice.\n"));
1114 rc.restore_client_name = ua->argv[i];
1120 } /* end strcase compare */
1121 } /* end keyword loop */
1123 * End of keyword for loop -- if not found, we got a bogus keyword
1126 Dmsg1(800, "%s not found\n", ua->argk[i]);
1128 * Special case for Job Name, it can be the first
1129 * keyword that has no value.
1131 if (!rc.job_name && !ua->argv[i]) {
1132 rc.job_name = ua->argk[i]; /* use keyword as job name */
1133 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1135 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1139 } /* end argc loop */
1141 Dmsg0(800, "Done scan.\n");
1143 if (rc.catalog_name) {
1144 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1145 if (rc.catalog == NULL) {
1146 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1149 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1150 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1154 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1158 rc.job = GetJobResWithName(rc.job_name);
1160 if (*rc.job_name != 0) {
1161 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1163 rc.job = select_job_resource(ua);
1165 Dmsg1(800, "Found job=%s\n", rc.job_name);
1167 } else if (!rc.job) {
1168 ua->send_msg(_("A job name must be specified.\n"));
1169 rc.job = select_job_resource(ua);
1173 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1174 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1179 rc.pool = GetPoolResWithName(rc.pool_name);
1181 if (*rc.pool_name != 0) {
1182 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1184 rc.pool = select_pool_resource(ua);
1186 } else if (!rc.pool) {
1187 rc.pool = rc.job->pool; /* use default */
1191 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1192 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1195 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1197 if (rc.store_name) {
1198 rc.store->store = GetStoreResWithName(rc.store_name);
1199 pm_strcpy(rc.store->store_source, _("command line"));
1200 if (!rc.store->store) {
1201 if (*rc.store_name != 0) {
1202 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1204 rc.store->store = select_storage_resource(ua);
1205 pm_strcpy(rc.store->store_source, _("user selection"));
1207 } else if (!rc.store->store) {
1208 get_job_storage(rc.store, rc.job, NULL); /* use default */
1210 if (!rc.store->store) {
1211 ua->error_msg(_("No storage specified.\n"));
1213 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1214 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1215 rc.store->store->name());
1218 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1220 if (rc.client_name) {
1221 rc.client = GetClientResWithName(rc.client_name);
1223 if (*rc.client_name != 0) {
1224 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name);
1226 rc.client = select_client_resource(ua);
1228 } else if (!rc.client) {
1229 rc.client = rc.job->client; /* use default */
1233 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1234 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1238 Dmsg1(800, "Using client=%s\n", rc.client->name());
1240 if (rc.restore_client_name) {
1241 rc.client = GetClientResWithName(rc.restore_client_name);
1243 if (*rc.restore_client_name != 0) {
1244 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1246 rc.client = select_client_resource(ua);
1248 } else if (!rc.client) {
1249 rc.client = rc.job->client; /* use default */
1253 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1254 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1258 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1261 if (rc.fileset_name) {
1262 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1264 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1265 rc.fileset = select_fileset_resource(ua);
1267 } else if (!rc.fileset) {
1268 rc.fileset = rc.job->fileset; /* use default */
1272 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1273 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1274 rc.fileset->name());
1278 if (rc.verify_job_name) {
1279 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1280 if (!rc.verify_job) {
1281 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1282 rc.verify_job = select_job_resource(ua);
1284 } else if (!rc.verify_job) {
1285 rc.verify_job = rc.job->verify_job;
1288 if (rc.previous_job_name) {
1289 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1290 if (!rc.previous_job) {
1291 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1292 rc.previous_job = select_job_resource(ua);
1295 rc.previous_job = rc.job->verify_job;