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 plus additions
11 that are listed in the file LICENSE.
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;
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 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);
222 /* Note, this is also MigrateJobId */
223 jcr->RestoreJobId = str_to_int64(rc.jid);
226 /* Run without prompting? */
227 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
232 * Prompt User to see if all run job parameters are correct, and
233 * allow him to modify them.
235 if (!display_job_parameters(ua, jcr, rc.job, rc.verify_list, rc.jid, rc.replace,
240 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
244 if (ua->cmd[0] == '.' && strncasecmp(ua->cmd, ".mod ", 5) == 0) {
245 Dmsg1(000, "got: %s\n", ua->cmd);
248 if (!scan_command_line_arguments(ua, rc)) {
255 * At user request modify parameters of job to be run.
257 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
260 start_prompt(ua, _("Parameters to modify:\n"));
261 add_prompt(ua, _("Level")); /* 0 */
262 add_prompt(ua, _("Storage")); /* 1 */
263 add_prompt(ua, _("Job")); /* 2 */
264 add_prompt(ua, _("FileSet")); /* 3 */
265 if (jcr->JobType == JT_RESTORE) {
266 add_prompt(ua, _("Restore Client")); /* 4 */
268 add_prompt(ua, _("Client")); /* 4 */
270 add_prompt(ua, _("When")); /* 5 */
271 add_prompt(ua, _("Priority")); /* 6 */
272 if (jcr->JobType == JT_BACKUP ||
273 jcr->JobType == JT_MIGRATE ||
274 jcr->JobType == JT_VERIFY) {
275 add_prompt(ua, _("Pool")); /* 7 */
276 if (jcr->JobType == JT_VERIFY) {
277 add_prompt(ua, _("Verify Job")); /* 8 */
279 } else if (jcr->JobType == JT_RESTORE) {
280 add_prompt(ua, _("Bootstrap")); /* 7 */
281 add_prompt(ua, _("Where")); /* 8 */
282 add_prompt(ua, _("File Relocation"));/* 9 */
283 add_prompt(ua, _("Replace")); /* 10 */
284 add_prompt(ua, _("JobId")); /* 11 */
286 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
289 select_job_level(ua, jcr);
293 rc.store->store = select_storage_resource(ua);
294 if (rc.store->store) {
295 pm_strcpy(rc.store->store_source, _("user selection"));
296 set_rwstorage(jcr, rc.store);
302 rc.job = select_job_resource(ua);
305 set_jcr_defaults(jcr, rc.job);
311 rc.fileset = select_fileset_resource(ua);
313 jcr->fileset = rc.fileset;
319 rc.client = select_client_resource(ua);
321 jcr->client = rc.client;
327 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
330 if (ua->cmd[0] == 0) {
331 jcr->sched_time = time(NULL);
333 jcr->sched_time = str_to_utime(ua->cmd);
334 if (jcr->sched_time == 0) {
335 ua->send_msg(_("Invalid time, using current time.\n"));
336 jcr->sched_time = time(NULL);
342 if (!get_pint(ua, _("Enter new Priority: "))) {
345 if (ua->pint32_val == 0) {
346 ua->send_msg(_("Priority must be a positive integer.\n"));
348 jcr->JobPriority = ua->pint32_val;
352 /* Pool or Bootstrap depending on JobType */
353 if (jcr->JobType == JT_BACKUP ||
354 jcr->JobType == JT_MIGRATE ||
355 jcr->JobType == JT_VERIFY) { /* Pool */
356 rc.pool = select_pool_resource(ua);
359 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
366 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
369 if (jcr->RestoreBootstrap) {
370 free(jcr->RestoreBootstrap);
371 jcr->RestoreBootstrap = NULL;
373 if (ua->cmd[0] != 0) {
374 jcr->RestoreBootstrap = bstrdup(ua->cmd);
375 fd = fopen(jcr->RestoreBootstrap, "rb");
377 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
378 jcr->RestoreBootstrap, strerror(errno));
379 free(jcr->RestoreBootstrap);
380 jcr->RestoreBootstrap = NULL;
388 if (jcr->JobType == JT_VERIFY) {
389 rc.verify_job = select_job_resource(ua);
391 jcr->verify_job = rc.verify_job;
396 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
399 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
400 free(jcr->RegexWhere);
401 jcr->RegexWhere = NULL;
407 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
410 jcr->where = bstrdup(ua->cmd);
413 /* File relocation */
414 select_where_regexp(ua, jcr);
418 start_prompt(ua, _("Replace:\n"));
419 for (i=0; ReplaceOptions[i].name; i++) {
420 add_prompt(ua, ReplaceOptions[i].name);
422 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
424 jcr->replace = ReplaceOptions[opt].token;
429 rc.jid = NULL; /* force reprompt */
430 jcr->RestoreJobId = 0;
431 if (jcr->RestoreBootstrap) {
432 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
435 case -1: /* error or cancel */
443 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
445 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
448 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
449 JobId = run_job(jcr);
450 free_jcr(jcr); /* release jcr */
452 ua->error_msg(_("Job failed.\n"));
455 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
461 ua->send_msg(_("Job not run.\n"));
463 return 0; /* do not run */
466 static void select_where_regexp(UAContext *ua, JCR *jcr)
469 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
470 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
473 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
474 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
476 start_prompt(ua, _("This will replace your current Where value\n"));
477 add_prompt(ua, _("Strip prefix")); /* 0 */
478 add_prompt(ua, _("Add prefix")); /* 1 */
479 add_prompt(ua, _("Add file suffix")); /* 2 */
480 add_prompt(ua, _("Enter a regexp")); /* 3 */
481 add_prompt(ua, _("Test filename manipulation")); /* 4 */
482 add_prompt(ua, _("Use this ?")); /* 5 */
484 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
487 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
488 if (strip_prefix) bfree(strip_prefix);
489 strip_prefix = bstrdup(ua->cmd);
495 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
496 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
500 if (add_prefix) bfree(add_prefix);
501 add_prefix = bstrdup(ua->cmd);
506 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
507 if (add_suffix) bfree(add_suffix);
508 add_suffix = bstrdup(ua->cmd);
513 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
514 if (rwhere) bfree(rwhere);
515 rwhere = bstrdup(ua->cmd);
524 if (rwhere && rwhere[0] != '\0') {
525 regs = get_bregexps(rwhere);
526 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
528 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
529 regexp = (char *) bmalloc (len * sizeof(char));
530 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
531 regs = get_bregexps(regexp);
532 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
533 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
539 ua->send_msg(_("Cannot use your regexp\n"));
543 while (get_cmd(ua, _("Please enter filename to test: "))) {
544 apply_bregexps(ua->cmd, regs, &result);
545 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
554 case -1: /* error or cancel */
560 /* replace the existing where */
566 /* replace the existing regexwhere */
567 if (jcr->RegexWhere) {
568 bfree(jcr->RegexWhere);
569 jcr->RegexWhere = NULL;
573 jcr->RegexWhere = bstrdup(rwhere);
574 } else if (strip_prefix || add_prefix || add_suffix) {
575 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
576 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
577 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
580 regs = get_bregexps(jcr->RegexWhere);
585 if (jcr->RegexWhere) {
586 bfree(jcr->RegexWhere);
587 jcr->RegexWhere = NULL;
589 ua->send_msg(_("Cannot use your regexp.\n"));
593 if (strip_prefix) bfree(strip_prefix);
594 if (add_prefix) bfree(add_prefix);
595 if (add_suffix) bfree(add_suffix);
596 if (rwhere) bfree(rwhere);
599 static void select_job_level(UAContext *ua, JCR *jcr)
601 if (jcr->JobType == JT_BACKUP) {
602 start_prompt(ua, _("Levels:\n"));
603 add_prompt(ua, _("Base"));
604 add_prompt(ua, _("Full"));
605 add_prompt(ua, _("Incremental"));
606 add_prompt(ua, _("Differential"));
607 add_prompt(ua, _("Since"));
608 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
610 jcr->JobLevel = L_BASE;
613 jcr->JobLevel = L_FULL;
616 jcr->JobLevel = L_INCREMENTAL;
619 jcr->JobLevel = L_DIFFERENTIAL;
622 jcr->JobLevel = L_SINCE;
627 } else if (jcr->JobType == JT_VERIFY) {
628 start_prompt(ua, _("Levels:\n"));
629 add_prompt(ua, _("Initialize Catalog"));
630 add_prompt(ua, _("Verify Catalog"));
631 add_prompt(ua, _("Verify Volume to Catalog"));
632 add_prompt(ua, _("Verify Disk to Catalog"));
633 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
634 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
636 jcr->JobLevel = L_VERIFY_INIT;
639 jcr->JobLevel = L_VERIFY_CATALOG;
642 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
645 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
648 jcr->JobLevel = L_VERIFY_DATA;
654 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
659 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
660 char *jid, const char *replace, char *client_name)
662 Dmsg1(800, "JobType=%c\n", jcr->JobType);
663 switch (jcr->JobType) {
665 char dt[MAX_TIME_LENGTH];
667 if (ua->api) ua->signal(BNET_RUN_CMD);
668 ua->send_msg(_("Run %s job\n"
677 jcr->fileset->name(),
678 NPRT(jcr->client->name()),
679 jcr->wstore?jcr->wstore->name():"*None*",
680 bstrutime(dt, sizeof(dt), jcr->sched_time),
682 jcr->JobLevel = L_FULL;
686 if (jcr->JobType == JT_BACKUP) {
687 if (ua->api) ua->signal(BNET_RUN_CMD);
688 ua->send_msg(_("Run %s job\n"
693 "Pool: %s (From %s)\n"
694 "Storage: %s (From %s)\n"
699 level_to_str(jcr->JobLevel),
701 jcr->fileset->name(),
702 NPRT(jcr->pool->name()), jcr->pool_source,
703 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
704 bstrutime(dt, sizeof(dt), jcr->sched_time),
706 } else { /* JT_VERIFY */
708 if (jcr->verify_job) {
709 Name = jcr->verify_job->name();
714 verify_list = job->WriteVerifyList;
719 if (ua->api) ua->signal(BNET_RUN_CMD);
720 ua->send_msg(_("Run %s job\n"
725 "Pool: %s (From %s)\n"
726 "Storage: %s (From %s)\n"
733 level_to_str(jcr->JobLevel),
735 jcr->fileset->name(),
736 NPRT(jcr->pool->name()), jcr->pool_source,
737 jcr->rstore->name(), jcr->rstore_source,
740 bstrutime(dt, sizeof(dt), jcr->sched_time),
745 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
747 jcr->RestoreJobId = str_to_int64(jid);
749 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
752 jcr->RestoreJobId = ua->int64_val;
755 jcr->JobLevel = L_FULL; /* default level */
756 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
757 if (jcr->RestoreJobId == 0) {
758 if (ua->api) ua->signal(BNET_RUN_CMD);
759 /* RegexWhere is take before RestoreWhere */
760 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
761 ua->send_msg(_("Run Restore job\n"
767 "Backup Client: %s\n"
768 "Restore Client: %s\n"
774 NPRT(jcr->RestoreBootstrap),
775 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
777 jcr->fileset->name(),
781 bstrutime(dt, sizeof(dt), jcr->sched_time),
782 jcr->catalog->name(),
786 ua->send_msg(_("Run Restore job\n"
792 "Backup Client: %s\n"
793 "Restore Client: %s\n"
799 NPRT(jcr->RestoreBootstrap),
800 jcr->where?jcr->where:NPRT(job->RestoreWhere),
802 jcr->fileset->name(),
806 bstrutime(dt, sizeof(dt), jcr->sched_time),
807 jcr->catalog->name(),
812 if (ua->api) ua->signal(BNET_RUN_CMD);
813 ua->send_msg(_("Run Restore job\n"
817 NPRT(jcr->RestoreBootstrap));
819 /* RegexWhere is take before RestoreWhere */
820 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
821 ua->send_msg(_("RegexWhere: %s\n"),
822 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
824 ua->send_msg(_("Where: %s\n"),
825 jcr->where?jcr->where:NPRT(job->RestoreWhere));
828 ua->send_msg(_("Replace: %s\n"
838 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
839 bstrutime(dt, sizeof(dt), jcr->sched_time),
840 jcr->catalog->name(),
845 jcr->JobLevel = L_FULL; /* default level */
846 if (ua->api) ua->signal(BNET_RUN_CMD);
847 ua->send_msg(_("Run Migration job\n"
852 "Pool: %s (From %s)\n"
853 "Read Storage: %s (From %s)\n"
854 "Write Storage: %s (From %s)\n"
860 NPRT(jcr->RestoreBootstrap),
862 jcr->fileset->name(),
863 NPRT(jcr->pool->name()), jcr->pool_source,
864 jcr->rstore->name(), jcr->rstore_source,
865 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
866 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
867 bstrutime(dt, sizeof(dt), jcr->sched_time),
868 jcr->catalog->name(),
872 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
879 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
883 static const char *kw[] = { /* command line arguments */
884 "job", /* Used in a switch() */
892 "regexwhere", /* 8 where string as a bregexp */
894 "bootstrap", /* 10 */
898 "yes", /* 14 -- if you change this change YES_POS too */
899 "verifyjob", /* 15 */
900 "files", /* 16 number of files to restore */
901 "catalog", /* 17 override catalog */
902 "since", /* 18 since */
903 "cloned", /* 19 cloned */
904 "verifylist", /* 20 verify output list */
905 "migrationjob", /* 21 migration job name */
907 "backupclient", /* 23 */
908 "restoreclient", /* 24 */
913 rc.catalog_name = NULL;
916 rc.store_name = NULL;
917 rc.client_name = NULL;
918 rc.restore_client_name = NULL;
919 rc.fileset_name = NULL;
920 rc.verify_job_name = NULL;
921 rc.previous_job_name = NULL;
924 for (i=1; i<ua->argc; i++) {
925 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
927 /* Keep looking until we find a good keyword */
928 for (j=0; !kw_ok && kw[j]; j++) {
929 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
930 /* Note, yes and run have no value, so do not fail */
931 if (!ua->argv[i] && j != YES_POS /*yes*/) {
932 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
935 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
939 ua->send_msg(_("Job name specified twice.\n"));
942 rc.job_name = ua->argv[i];
946 if (rc.jid && !rc.mod) {
947 ua->send_msg(_("JobId specified twice.\n"));
950 rc.jid = ua->argv[i];
955 if (rc.client_name) {
956 ua->send_msg(_("Client specified twice.\n"));
959 rc.client_name = ua->argv[i];
962 case 4: /* fileset */
963 if (rc.fileset_name) {
964 ua->send_msg(_("FileSet specified twice.\n"));
967 rc.fileset_name = ua->argv[i];
972 ua->send_msg(_("Level specified twice.\n"));
975 rc.level_name = ua->argv[i];
978 case 6: /* storage */
981 ua->send_msg(_("Storage specified twice.\n"));
984 rc.store_name = ua->argv[i];
987 case 8: /* regexwhere */
988 if ((rc.regexwhere || rc.where) && !rc.mod) {
989 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
992 rc.regexwhere = ua->argv[i];
993 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
994 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
1000 if ((rc.where || rc.regexwhere) && !rc.mod) {
1001 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
1004 rc.where = ua->argv[i];
1005 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
1006 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
1011 case 10: /* bootstrap */
1012 if (rc.bootstrap && !rc.mod) {
1013 ua->send_msg(_("Bootstrap specified twice.\n"));
1016 rc.bootstrap = ua->argv[i];
1019 case 11: /* replace */
1020 if (rc.replace && !rc.mod) {
1021 ua->send_msg(_("Replace specified twice.\n"));
1024 rc.replace = ua->argv[i];
1028 if (rc.when && !rc.mod) {
1029 ua->send_msg(_("When specified twice.\n"));
1032 rc.when = ua->argv[i];
1035 case 13: /* Priority */
1036 if (rc.Priority && !rc.mod) {
1037 ua->send_msg(_("Priority specified twice.\n"));
1040 rc.Priority = atoi(ua->argv[i]);
1041 if (rc.Priority <= 0) {
1042 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1050 case 15: /* Verify Job */
1051 if (rc.verify_job_name) {
1052 ua->send_msg(_("Verify Job specified twice.\n"));
1055 rc.verify_job_name = ua->argv[i];
1058 case 16: /* files */
1059 rc.files = atoi(ua->argv[i]);
1063 case 17: /* catalog */
1064 rc.catalog_name = ua->argv[i];
1068 case 18: /* since */
1069 rc.since = ua->argv[i];
1073 case 19: /* cloned */
1078 case 20: /* write verify list output */
1079 rc.verify_list = ua->argv[i];
1082 case 21: /* Migration Job */
1083 if (rc.previous_job_name) {
1084 ua->send_msg(_("Migration Job specified twice.\n"));
1087 rc.previous_job_name = ua->argv[i];
1092 ua->send_msg(_("Pool specified twice.\n"));
1095 rc.pool_name = ua->argv[i];
1098 case 23: /* backupclient */
1099 if (rc.client_name) {
1100 ua->send_msg(_("Client specified twice.\n"));
1103 rc.client_name = ua->argv[i];
1106 case 24: /* restoreclient */
1107 if (rc.restore_client_name && !rc.mod) {
1108 ua->send_msg(_("Restore Client specified twice.\n"));
1111 rc.restore_client_name = ua->argv[i];
1117 } /* end strcase compare */
1118 } /* end keyword loop */
1120 * End of keyword for loop -- if not found, we got a bogus keyword
1123 Dmsg1(800, "%s not found\n", ua->argk[i]);
1125 * Special case for Job Name, it can be the first
1126 * keyword that has no value.
1128 if (!rc.job_name && !ua->argv[i]) {
1129 rc.job_name = ua->argk[i]; /* use keyword as job name */
1130 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1132 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1136 } /* end argc loop */
1138 Dmsg0(800, "Done scan.\n");
1140 if (rc.catalog_name) {
1141 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1142 if (rc.catalog == NULL) {
1143 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1146 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1147 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1151 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1155 rc.job = GetJobResWithName(rc.job_name);
1157 if (*rc.job_name != 0) {
1158 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1160 rc.job = select_job_resource(ua);
1162 Dmsg1(800, "Found job=%s\n", rc.job_name);
1164 } else if (!rc.job) {
1165 ua->send_msg(_("A job name must be specified.\n"));
1166 rc.job = select_job_resource(ua);
1170 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1171 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1176 rc.pool = GetPoolResWithName(rc.pool_name);
1178 if (*rc.pool_name != 0) {
1179 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1181 rc.pool = select_pool_resource(ua);
1183 } else if (!rc.pool) {
1184 rc.pool = rc.job->pool; /* use default */
1188 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1189 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1192 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1194 if (rc.store_name) {
1195 rc.store->store = GetStoreResWithName(rc.store_name);
1196 pm_strcpy(rc.store->store_source, _("command line"));
1197 if (!rc.store->store) {
1198 if (*rc.store_name != 0) {
1199 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1201 rc.store->store = select_storage_resource(ua);
1202 pm_strcpy(rc.store->store_source, _("user selection"));
1204 } else if (!rc.store->store) {
1205 get_job_storage(rc.store, rc.job, NULL); /* use default */
1207 if (!rc.store->store) {
1208 ua->error_msg(_("No storage specified.\n"));
1210 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1211 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1212 rc.store->store->name());
1215 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1217 if (rc.client_name) {
1218 rc.client = GetClientResWithName(rc.client_name);
1220 if (*rc.client_name != 0) {
1221 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name);
1223 rc.client = select_client_resource(ua);
1225 } else if (!rc.client) {
1226 rc.client = rc.job->client; /* use default */
1230 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1231 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1235 Dmsg1(800, "Using client=%s\n", rc.client->name());
1237 if (rc.restore_client_name) {
1238 rc.client = GetClientResWithName(rc.restore_client_name);
1240 if (*rc.restore_client_name != 0) {
1241 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1243 rc.client = select_client_resource(ua);
1245 } else if (!rc.client) {
1246 rc.client = rc.job->client; /* use default */
1250 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1251 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1255 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1258 if (rc.fileset_name) {
1259 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1261 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1262 rc.fileset = select_fileset_resource(ua);
1264 } else if (!rc.fileset) {
1265 rc.fileset = rc.job->fileset; /* use default */
1269 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1270 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1271 rc.fileset->name());
1275 if (rc.verify_job_name) {
1276 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1277 if (!rc.verify_job) {
1278 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1279 rc.verify_job = select_job_resource(ua);
1281 } else if (!rc.verify_job) {
1282 rc.verify_job = rc.job->verify_job;
1285 if (rc.previous_job_name) {
1286 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1287 if (!rc.previous_job) {
1288 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1289 rc.previous_job = select_job_resource(ua);
1292 rc.previous_job = rc.job->verify_job;