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");
379 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
380 jcr->RestoreBootstrap, strerror(errno));
381 free(jcr->RestoreBootstrap);
382 jcr->RestoreBootstrap = NULL;
390 if (jcr->JobType == JT_VERIFY) {
391 rc.verify_job = select_job_resource(ua);
393 jcr->verify_job = rc.verify_job;
398 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
401 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
402 free(jcr->RegexWhere);
403 jcr->RegexWhere = NULL;
409 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
412 jcr->where = bstrdup(ua->cmd);
415 /* File relocation */
416 select_where_regexp(ua, jcr);
420 start_prompt(ua, _("Replace:\n"));
421 for (i=0; ReplaceOptions[i].name; i++) {
422 add_prompt(ua, ReplaceOptions[i].name);
424 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
426 jcr->replace = ReplaceOptions[opt].token;
431 rc.jid = NULL; /* force reprompt */
432 jcr->RestoreJobId = 0;
433 if (jcr->RestoreBootstrap) {
434 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
437 case -1: /* error or cancel */
445 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
447 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
450 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
451 JobId = run_job(jcr);
452 free_jcr(jcr); /* release jcr */
454 ua->error_msg(_("Job failed.\n"));
457 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
463 ua->send_msg(_("Job not run.\n"));
465 return 0; /* do not run */
468 static void select_where_regexp(UAContext *ua, JCR *jcr)
471 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
472 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
475 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
476 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
478 start_prompt(ua, _("This will replace your current Where value\n"));
479 add_prompt(ua, _("Strip prefix")); /* 0 */
480 add_prompt(ua, _("Add prefix")); /* 1 */
481 add_prompt(ua, _("Add file suffix")); /* 2 */
482 add_prompt(ua, _("Enter a regexp")); /* 3 */
483 add_prompt(ua, _("Test filename manipulation")); /* 4 */
484 add_prompt(ua, _("Use this ?")); /* 5 */
486 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
489 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
490 if (strip_prefix) bfree(strip_prefix);
491 strip_prefix = bstrdup(ua->cmd);
497 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
498 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
502 if (add_prefix) bfree(add_prefix);
503 add_prefix = bstrdup(ua->cmd);
508 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
509 if (add_suffix) bfree(add_suffix);
510 add_suffix = bstrdup(ua->cmd);
515 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
516 if (rwhere) bfree(rwhere);
517 rwhere = bstrdup(ua->cmd);
526 if (rwhere && rwhere[0] != '\0') {
527 regs = get_bregexps(rwhere);
528 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
530 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
531 regexp = (char *) bmalloc (len * sizeof(char));
532 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
533 regs = get_bregexps(regexp);
534 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
535 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
541 ua->send_msg(_("Cannot use your regexp\n"));
545 while (get_cmd(ua, _("Please enter filename to test: "))) {
546 apply_bregexps(ua->cmd, regs, &result);
547 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
556 case -1: /* error or cancel */
562 /* replace the existing where */
568 /* replace the existing regexwhere */
569 if (jcr->RegexWhere) {
570 bfree(jcr->RegexWhere);
571 jcr->RegexWhere = NULL;
575 jcr->RegexWhere = bstrdup(rwhere);
576 } else if (strip_prefix || add_prefix || add_suffix) {
577 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
578 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
579 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
582 regs = get_bregexps(jcr->RegexWhere);
587 if (jcr->RegexWhere) {
588 bfree(jcr->RegexWhere);
589 jcr->RegexWhere = NULL;
591 ua->send_msg(_("Cannot use your regexp.\n"));
595 if (strip_prefix) bfree(strip_prefix);
596 if (add_prefix) bfree(add_prefix);
597 if (add_suffix) bfree(add_suffix);
598 if (rwhere) bfree(rwhere);
601 static void select_job_level(UAContext *ua, JCR *jcr)
603 if (jcr->JobType == JT_BACKUP) {
604 start_prompt(ua, _("Levels:\n"));
605 add_prompt(ua, _("Base"));
606 add_prompt(ua, _("Full"));
607 add_prompt(ua, _("Incremental"));
608 add_prompt(ua, _("Differential"));
609 add_prompt(ua, _("Since"));
610 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
612 jcr->JobLevel = L_BASE;
615 jcr->JobLevel = L_FULL;
618 jcr->JobLevel = L_INCREMENTAL;
621 jcr->JobLevel = L_DIFFERENTIAL;
624 jcr->JobLevel = L_SINCE;
629 } else if (jcr->JobType == JT_VERIFY) {
630 start_prompt(ua, _("Levels:\n"));
631 add_prompt(ua, _("Initialize Catalog"));
632 add_prompt(ua, _("Verify Catalog"));
633 add_prompt(ua, _("Verify Volume to Catalog"));
634 add_prompt(ua, _("Verify Disk to Catalog"));
635 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
636 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
638 jcr->JobLevel = L_VERIFY_INIT;
641 jcr->JobLevel = L_VERIFY_CATALOG;
644 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
647 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
650 jcr->JobLevel = L_VERIFY_DATA;
656 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
661 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, const char *verify_list,
662 char *jid, const char *replace, char *client_name)
664 Dmsg1(800, "JobType=%c\n", jcr->JobType);
665 switch (jcr->JobType) {
667 char dt[MAX_TIME_LENGTH];
669 if (ua->api) ua->signal(BNET_RUN_CMD);
670 ua->send_msg(_("Run %s job\n"
679 jcr->fileset->name(),
680 NPRT(jcr->client->name()),
681 jcr->wstore?jcr->wstore->name():"*None*",
682 bstrutime(dt, sizeof(dt), jcr->sched_time),
684 jcr->JobLevel = L_FULL;
688 if (jcr->JobType == JT_BACKUP) {
689 if (ua->api) ua->signal(BNET_RUN_CMD);
690 ua->send_msg(_("Run %s job\n"
695 "Pool: %s (From %s)\n"
696 "Storage: %s (From %s)\n"
701 level_to_str(jcr->JobLevel),
703 jcr->fileset->name(),
704 NPRT(jcr->pool->name()), jcr->pool_source,
705 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
706 bstrutime(dt, sizeof(dt), jcr->sched_time),
708 } else { /* JT_VERIFY */
710 if (jcr->verify_job) {
711 Name = jcr->verify_job->name();
716 verify_list = job->WriteVerifyList;
721 if (ua->api) ua->signal(BNET_RUN_CMD);
722 ua->send_msg(_("Run %s job\n"
727 "Pool: %s (From %s)\n"
728 "Storage: %s (From %s)\n"
735 level_to_str(jcr->JobLevel),
737 jcr->fileset->name(),
738 NPRT(jcr->pool->name()), jcr->pool_source,
739 jcr->rstore->name(), jcr->rstore_source,
742 bstrutime(dt, sizeof(dt), jcr->sched_time),
747 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
749 jcr->RestoreJobId = str_to_int64(jid);
751 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
754 jcr->RestoreJobId = ua->int64_val;
757 jcr->JobLevel = L_FULL; /* default level */
758 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
759 if (jcr->RestoreJobId == 0) {
760 if (ua->api) ua->signal(BNET_RUN_CMD);
761 /* RegexWhere is take before RestoreWhere */
762 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
763 ua->send_msg(_("Run Restore job\n"
769 "Backup Client: %s\n"
770 "Restore Client: %s\n"
776 NPRT(jcr->RestoreBootstrap),
777 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
779 jcr->fileset->name(),
783 bstrutime(dt, sizeof(dt), jcr->sched_time),
784 jcr->catalog->name(),
788 ua->send_msg(_("Run Restore job\n"
794 "Backup Client: %s\n"
795 "Restore Client: %s\n"
801 NPRT(jcr->RestoreBootstrap),
802 jcr->where?jcr->where:NPRT(job->RestoreWhere),
804 jcr->fileset->name(),
808 bstrutime(dt, sizeof(dt), jcr->sched_time),
809 jcr->catalog->name(),
814 if (ua->api) ua->signal(BNET_RUN_CMD);
815 ua->send_msg(_("Run Restore job\n"
819 NPRT(jcr->RestoreBootstrap));
821 /* RegexWhere is take before RestoreWhere */
822 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
823 ua->send_msg(_("RegexWhere: %s\n"),
824 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
826 ua->send_msg(_("Where: %s\n"),
827 jcr->where?jcr->where:NPRT(job->RestoreWhere));
830 ua->send_msg(_("Replace: %s\n"
840 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
841 bstrutime(dt, sizeof(dt), jcr->sched_time),
842 jcr->catalog->name(),
847 jcr->JobLevel = L_FULL; /* default level */
848 if (ua->api) ua->signal(BNET_RUN_CMD);
849 ua->send_msg(_("Run Migration job\n"
854 "Pool: %s (From %s)\n"
855 "Read Storage: %s (From %s)\n"
856 "Write Storage: %s (From %s)\n"
862 NPRT(jcr->RestoreBootstrap),
864 jcr->fileset->name(),
865 NPRT(jcr->pool->name()), jcr->pool_source,
866 jcr->rstore->name(), jcr->rstore_source,
867 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
868 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
869 bstrutime(dt, sizeof(dt), jcr->sched_time),
870 jcr->catalog->name(),
874 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
881 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
885 static const char *kw[] = { /* command line arguments */
886 "job", /* Used in a switch() */
894 "regexwhere", /* 8 where string as a bregexp */
896 "bootstrap", /* 10 */
900 "yes", /* 14 -- if you change this change YES_POS too */
901 "verifyjob", /* 15 */
902 "files", /* 16 number of files to restore */
903 "catalog", /* 17 override catalog */
904 "since", /* 18 since */
905 "cloned", /* 19 cloned */
906 "verifylist", /* 20 verify output list */
907 "migrationjob", /* 21 migration job name */
909 "backupclient", /* 23 */
910 "restoreclient", /* 24 */
915 rc.catalog_name = NULL;
918 rc.store_name = NULL;
919 rc.client_name = NULL;
920 rc.restore_client_name = NULL;
921 rc.fileset_name = NULL;
922 rc.verify_job_name = NULL;
923 rc.previous_job_name = NULL;
926 for (i=1; i<ua->argc; i++) {
927 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
929 /* Keep looking until we find a good keyword */
930 for (j=0; !kw_ok && kw[j]; j++) {
931 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
932 /* Note, yes and run have no value, so do not fail */
933 if (!ua->argv[i] && j != YES_POS /*yes*/) {
934 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
937 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
941 ua->send_msg(_("Job name specified twice.\n"));
944 rc.job_name = ua->argv[i];
948 if (rc.jid && !rc.mod) {
949 ua->send_msg(_("JobId specified twice.\n"));
952 rc.jid = ua->argv[i];
957 if (rc.client_name) {
958 ua->send_msg(_("Client specified twice.\n"));
961 rc.client_name = ua->argv[i];
964 case 4: /* fileset */
965 if (rc.fileset_name) {
966 ua->send_msg(_("FileSet specified twice.\n"));
969 rc.fileset_name = ua->argv[i];
974 ua->send_msg(_("Level specified twice.\n"));
977 rc.level_name = ua->argv[i];
980 case 6: /* storage */
983 ua->send_msg(_("Storage specified twice.\n"));
986 rc.store_name = ua->argv[i];
989 case 8: /* regexwhere */
990 if ((rc.regexwhere || rc.where) && !rc.mod) {
991 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
994 rc.regexwhere = ua->argv[i];
995 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
996 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
1002 if ((rc.where || rc.regexwhere) && !rc.mod) {
1003 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
1006 rc.where = ua->argv[i];
1007 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
1008 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
1013 case 10: /* bootstrap */
1014 if (rc.bootstrap && !rc.mod) {
1015 ua->send_msg(_("Bootstrap specified twice.\n"));
1018 rc.bootstrap = ua->argv[i];
1021 case 11: /* replace */
1022 if (rc.replace && !rc.mod) {
1023 ua->send_msg(_("Replace specified twice.\n"));
1026 rc.replace = ua->argv[i];
1030 if (rc.when && !rc.mod) {
1031 ua->send_msg(_("When specified twice.\n"));
1034 rc.when = ua->argv[i];
1037 case 13: /* Priority */
1038 if (rc.Priority && !rc.mod) {
1039 ua->send_msg(_("Priority specified twice.\n"));
1042 rc.Priority = atoi(ua->argv[i]);
1043 if (rc.Priority <= 0) {
1044 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1052 case 15: /* Verify Job */
1053 if (rc.verify_job_name) {
1054 ua->send_msg(_("Verify Job specified twice.\n"));
1057 rc.verify_job_name = ua->argv[i];
1060 case 16: /* files */
1061 rc.files = atoi(ua->argv[i]);
1065 case 17: /* catalog */
1066 rc.catalog_name = ua->argv[i];
1070 case 18: /* since */
1071 rc.since = ua->argv[i];
1075 case 19: /* cloned */
1080 case 20: /* write verify list output */
1081 rc.verify_list = ua->argv[i];
1084 case 21: /* Migration Job */
1085 if (rc.previous_job_name) {
1086 ua->send_msg(_("Migration Job specified twice.\n"));
1089 rc.previous_job_name = ua->argv[i];
1094 ua->send_msg(_("Pool specified twice.\n"));
1097 rc.pool_name = ua->argv[i];
1100 case 23: /* backupclient */
1101 if (rc.client_name) {
1102 ua->send_msg(_("Client specified twice.\n"));
1105 rc.client_name = ua->argv[i];
1108 case 24: /* restoreclient */
1109 if (rc.restore_client_name && !rc.mod) {
1110 ua->send_msg(_("Restore Client specified twice.\n"));
1113 rc.restore_client_name = ua->argv[i];
1119 } /* end strcase compare */
1120 } /* end keyword loop */
1122 * End of keyword for loop -- if not found, we got a bogus keyword
1125 Dmsg1(800, "%s not found\n", ua->argk[i]);
1127 * Special case for Job Name, it can be the first
1128 * keyword that has no value.
1130 if (!rc.job_name && !ua->argv[i]) {
1131 rc.job_name = ua->argk[i]; /* use keyword as job name */
1132 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1134 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1138 } /* end argc loop */
1140 Dmsg0(800, "Done scan.\n");
1142 if (rc.catalog_name) {
1143 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1144 if (rc.catalog == NULL) {
1145 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1148 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1149 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1153 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1157 rc.job = GetJobResWithName(rc.job_name);
1159 if (*rc.job_name != 0) {
1160 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1162 rc.job = select_job_resource(ua);
1164 Dmsg1(800, "Found job=%s\n", rc.job_name);
1166 } else if (!rc.job) {
1167 ua->send_msg(_("A job name must be specified.\n"));
1168 rc.job = select_job_resource(ua);
1172 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1173 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1178 rc.pool = GetPoolResWithName(rc.pool_name);
1180 if (*rc.pool_name != 0) {
1181 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1183 rc.pool = select_pool_resource(ua);
1185 } else if (!rc.pool) {
1186 rc.pool = rc.job->pool; /* use default */
1190 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1191 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1194 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1196 if (rc.store_name) {
1197 rc.store->store = GetStoreResWithName(rc.store_name);
1198 pm_strcpy(rc.store->store_source, _("command line"));
1199 if (!rc.store->store) {
1200 if (*rc.store_name != 0) {
1201 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1203 rc.store->store = select_storage_resource(ua);
1204 pm_strcpy(rc.store->store_source, _("user selection"));
1206 } else if (!rc.store->store) {
1207 get_job_storage(rc.store, rc.job, NULL); /* use default */
1209 if (!rc.store->store) {
1210 ua->error_msg(_("No storage specified.\n"));
1212 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1213 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1214 rc.store->store->name());
1217 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1219 if (rc.client_name) {
1220 rc.client = GetClientResWithName(rc.client_name);
1222 if (*rc.client_name != 0) {
1223 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name);
1225 rc.client = select_client_resource(ua);
1227 } else if (!rc.client) {
1228 rc.client = rc.job->client; /* use default */
1232 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1233 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1237 Dmsg1(800, "Using client=%s\n", rc.client->name());
1239 if (rc.restore_client_name) {
1240 rc.client = GetClientResWithName(rc.restore_client_name);
1242 if (*rc.restore_client_name != 0) {
1243 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1245 rc.client = select_client_resource(ua);
1247 } else if (!rc.client) {
1248 rc.client = rc.job->client; /* use default */
1252 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1253 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1257 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1260 if (rc.fileset_name) {
1261 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1263 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1264 rc.fileset = select_fileset_resource(ua);
1266 } else if (!rc.fileset) {
1267 rc.fileset = rc.job->fileset; /* use default */
1271 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1272 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1273 rc.fileset->name());
1277 if (rc.verify_job_name) {
1278 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1279 if (!rc.verify_job) {
1280 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1281 rc.verify_job = select_job_resource(ua);
1283 } else if (!rc.verify_job) {
1284 rc.verify_job = rc.job->verify_job;
1287 if (rc.previous_job_name) {
1288 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1289 if (!rc.previous_job) {
1290 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1291 rc.previous_job = select_job_resource(ua);
1294 rc.previous_job = rc.job->verify_job;