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;
217 if (!get_level_from_name(jcr, rc.level_name)) {
218 ua->send_msg(_("Level %s not valid.\n"), rc.level_name);
221 rc.level_name = NULL;
224 /* Note, this is also MigrateJobId */
225 jcr->RestoreJobId = str_to_int64(rc.jid);
229 /* Run without prompting? */
230 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
235 * Prompt User to see if all run job parameters are correct, and
236 * allow him to modify them.
238 if (!display_job_parameters(ua, jcr, rc.job, rc.verify_list, rc.jid, rc.replace,
243 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
247 if (strncasecmp(ua->cmd, ".mod ", 5) == 0 ||
248 (strncasecmp(ua->cmd, "mod ", 4) == 0 && strlen(ua->cmd) > 6)) {
249 Dmsg1(000, "got: %s\n", ua->cmd);
252 if (!scan_command_line_arguments(ua, rc)) {
259 * At user request modify parameters of job to be run.
261 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
264 start_prompt(ua, _("Parameters to modify:\n"));
265 add_prompt(ua, _("Level")); /* 0 */
266 add_prompt(ua, _("Storage")); /* 1 */
267 add_prompt(ua, _("Job")); /* 2 */
268 add_prompt(ua, _("FileSet")); /* 3 */
269 if (jcr->JobType == JT_RESTORE) {
270 add_prompt(ua, _("Restore Client")); /* 4 */
272 add_prompt(ua, _("Client")); /* 4 */
274 add_prompt(ua, _("When")); /* 5 */
275 add_prompt(ua, _("Priority")); /* 6 */
276 if (jcr->JobType == JT_BACKUP ||
277 jcr->JobType == JT_MIGRATE ||
278 jcr->JobType == JT_VERIFY) {
279 add_prompt(ua, _("Pool")); /* 7 */
280 if (jcr->JobType == JT_VERIFY) {
281 add_prompt(ua, _("Verify Job")); /* 8 */
283 } else if (jcr->JobType == JT_RESTORE) {
284 add_prompt(ua, _("Bootstrap")); /* 7 */
285 add_prompt(ua, _("Where")); /* 8 */
286 add_prompt(ua, _("File Relocation"));/* 9 */
287 add_prompt(ua, _("Replace")); /* 10 */
288 add_prompt(ua, _("JobId")); /* 11 */
290 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
293 select_job_level(ua, jcr);
297 rc.store->store = select_storage_resource(ua);
298 if (rc.store->store) {
299 pm_strcpy(rc.store->store_source, _("user selection"));
300 set_rwstorage(jcr, rc.store);
306 rc.job = select_job_resource(ua);
309 set_jcr_defaults(jcr, rc.job);
315 rc.fileset = select_fileset_resource(ua);
317 jcr->fileset = rc.fileset;
323 rc.client = select_client_resource(ua);
325 jcr->client = rc.client;
331 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
334 if (ua->cmd[0] == 0) {
335 jcr->sched_time = time(NULL);
337 jcr->sched_time = str_to_utime(ua->cmd);
338 if (jcr->sched_time == 0) {
339 ua->send_msg(_("Invalid time, using current time.\n"));
340 jcr->sched_time = time(NULL);
346 if (!get_pint(ua, _("Enter new Priority: "))) {
349 if (ua->pint32_val == 0) {
350 ua->send_msg(_("Priority must be a positive integer.\n"));
352 jcr->JobPriority = ua->pint32_val;
356 /* Pool or Bootstrap depending on JobType */
357 if (jcr->JobType == JT_BACKUP ||
358 jcr->JobType == JT_MIGRATE ||
359 jcr->JobType == JT_VERIFY) { /* Pool */
360 rc.pool = select_pool_resource(ua);
363 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
370 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
373 if (jcr->RestoreBootstrap) {
374 free(jcr->RestoreBootstrap);
375 jcr->RestoreBootstrap = NULL;
377 if (ua->cmd[0] != 0) {
378 jcr->RestoreBootstrap = bstrdup(ua->cmd);
379 fd = fopen(jcr->RestoreBootstrap, "rb");
381 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
382 jcr->RestoreBootstrap, strerror(errno));
383 free(jcr->RestoreBootstrap);
384 jcr->RestoreBootstrap = NULL;
392 if (jcr->JobType == JT_VERIFY) {
393 rc.verify_job = select_job_resource(ua);
395 jcr->verify_job = rc.verify_job;
400 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
403 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
404 free(jcr->RegexWhere);
405 jcr->RegexWhere = NULL;
411 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
414 jcr->where = bstrdup(ua->cmd);
417 /* File relocation */
418 select_where_regexp(ua, jcr);
422 start_prompt(ua, _("Replace:\n"));
423 for (i=0; ReplaceOptions[i].name; i++) {
424 add_prompt(ua, ReplaceOptions[i].name);
426 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
428 jcr->replace = ReplaceOptions[opt].token;
433 rc.jid = NULL; /* force reprompt */
434 jcr->RestoreJobId = 0;
435 if (jcr->RestoreBootstrap) {
436 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
439 case -1: /* error or cancel */
447 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
449 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
452 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
453 JobId = run_job(jcr);
454 free_jcr(jcr); /* release jcr */
456 ua->error_msg(_("Job failed.\n"));
459 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
465 ua->send_msg(_("Job not run.\n"));
467 return 0; /* do not run */
470 static void select_where_regexp(UAContext *ua, JCR *jcr)
473 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
474 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
477 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
478 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
480 start_prompt(ua, _("This will replace your current Where value\n"));
481 add_prompt(ua, _("Strip prefix")); /* 0 */
482 add_prompt(ua, _("Add prefix")); /* 1 */
483 add_prompt(ua, _("Add file suffix")); /* 2 */
484 add_prompt(ua, _("Enter a regexp")); /* 3 */
485 add_prompt(ua, _("Test filename manipulation")); /* 4 */
486 add_prompt(ua, _("Use this ?")); /* 5 */
488 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
491 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
492 if (strip_prefix) bfree(strip_prefix);
493 strip_prefix = bstrdup(ua->cmd);
499 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
500 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
504 if (add_prefix) bfree(add_prefix);
505 add_prefix = bstrdup(ua->cmd);
510 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
511 if (add_suffix) bfree(add_suffix);
512 add_suffix = bstrdup(ua->cmd);
517 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
518 if (rwhere) bfree(rwhere);
519 rwhere = bstrdup(ua->cmd);
528 if (rwhere && rwhere[0] != '\0') {
529 regs = get_bregexps(rwhere);
530 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
532 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
533 regexp = (char *) bmalloc (len * sizeof(char));
534 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
535 regs = get_bregexps(regexp);
536 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
537 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
543 ua->send_msg(_("Cannot use your regexp\n"));
547 while (get_cmd(ua, _("Please enter filename to test: "))) {
548 apply_bregexps(ua->cmd, regs, &result);
549 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
558 case -1: /* error or cancel */
564 /* replace the existing where */
570 /* replace the existing regexwhere */
571 if (jcr->RegexWhere) {
572 bfree(jcr->RegexWhere);
573 jcr->RegexWhere = NULL;
577 jcr->RegexWhere = bstrdup(rwhere);
578 } else if (strip_prefix || add_prefix || add_suffix) {
579 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
580 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
581 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
584 regs = get_bregexps(jcr->RegexWhere);
589 if (jcr->RegexWhere) {
590 bfree(jcr->RegexWhere);
591 jcr->RegexWhere = NULL;
593 ua->send_msg(_("Cannot use your regexp.\n"));
597 if (strip_prefix) bfree(strip_prefix);
598 if (add_prefix) bfree(add_prefix);
599 if (add_suffix) bfree(add_suffix);
600 if (rwhere) bfree(rwhere);
603 static void select_job_level(UAContext *ua, JCR *jcr)
605 if (jcr->JobType == JT_BACKUP) {
606 start_prompt(ua, _("Levels:\n"));
607 add_prompt(ua, _("Base"));
608 add_prompt(ua, _("Full"));
609 add_prompt(ua, _("Incremental"));
610 add_prompt(ua, _("Differential"));
611 add_prompt(ua, _("Since"));
612 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
614 jcr->JobLevel = L_BASE;
617 jcr->JobLevel = L_FULL;
620 jcr->JobLevel = L_INCREMENTAL;
623 jcr->JobLevel = L_DIFFERENTIAL;
626 jcr->JobLevel = L_SINCE;
631 } else if (jcr->JobType == JT_VERIFY) {
632 start_prompt(ua, _("Levels:\n"));
633 add_prompt(ua, _("Initialize Catalog"));
634 add_prompt(ua, _("Verify Catalog"));
635 add_prompt(ua, _("Verify Volume to Catalog"));
636 add_prompt(ua, _("Verify Disk to Catalog"));
637 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
638 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
640 jcr->JobLevel = L_VERIFY_INIT;
643 jcr->JobLevel = L_VERIFY_CATALOG;
646 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
649 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
652 jcr->JobLevel = L_VERIFY_DATA;
658 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
663 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
664 char *jid, const char *replace, char *client_name)
666 Dmsg1(800, "JobType=%c\n", jcr->JobType);
667 switch (jcr->JobType) {
669 char dt[MAX_TIME_LENGTH];
671 if (ua->api) ua->signal(BNET_RUN_CMD);
672 ua->send_msg(_("Run %s job\n"
681 jcr->fileset->name(),
682 NPRT(jcr->client->name()),
683 jcr->wstore?jcr->wstore->name():"*None*",
684 bstrutime(dt, sizeof(dt), jcr->sched_time),
686 jcr->JobLevel = L_FULL;
690 if (jcr->JobType == JT_BACKUP) {
691 if (ua->api) ua->signal(BNET_RUN_CMD);
692 ua->send_msg(_("Run %s job\n"
697 "Pool: %s (From %s)\n"
698 "Storage: %s (From %s)\n"
703 level_to_str(jcr->JobLevel),
705 jcr->fileset->name(),
706 NPRT(jcr->pool->name()), jcr->pool_source,
707 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
708 bstrutime(dt, sizeof(dt), jcr->sched_time),
710 } else { /* JT_VERIFY */
712 if (jcr->verify_job) {
713 Name = jcr->verify_job->name();
718 verify_list = job->WriteVerifyList;
723 if (ua->api) ua->signal(BNET_RUN_CMD);
724 ua->send_msg(_("Run %s job\n"
729 "Pool: %s (From %s)\n"
730 "Storage: %s (From %s)\n"
737 level_to_str(jcr->JobLevel),
739 jcr->fileset->name(),
740 NPRT(jcr->pool->name()), jcr->pool_source,
741 jcr->rstore->name(), jcr->rstore_source,
744 bstrutime(dt, sizeof(dt), jcr->sched_time),
749 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
751 jcr->RestoreJobId = str_to_int64(jid);
753 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
756 jcr->RestoreJobId = ua->int64_val;
759 jcr->JobLevel = L_FULL; /* default level */
760 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
761 if (jcr->RestoreJobId == 0) {
762 if (ua->api) ua->signal(BNET_RUN_CMD);
763 /* RegexWhere is take before RestoreWhere */
764 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
765 ua->send_msg(_("Run Restore job\n"
771 "Backup Client: %s\n"
772 "Restore Client: %s\n"
778 NPRT(jcr->RestoreBootstrap),
779 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
781 jcr->fileset->name(),
785 bstrutime(dt, sizeof(dt), jcr->sched_time),
786 jcr->catalog->name(),
790 ua->send_msg(_("Run Restore job\n"
796 "Backup Client: %s\n"
797 "Restore Client: %s\n"
803 NPRT(jcr->RestoreBootstrap),
804 jcr->where?jcr->where:NPRT(job->RestoreWhere),
806 jcr->fileset->name(),
810 bstrutime(dt, sizeof(dt), jcr->sched_time),
811 jcr->catalog->name(),
816 if (ua->api) ua->signal(BNET_RUN_CMD);
817 ua->send_msg(_("Run Restore job\n"
821 NPRT(jcr->RestoreBootstrap));
823 /* RegexWhere is take before RestoreWhere */
824 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
825 ua->send_msg(_("RegexWhere: %s\n"),
826 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
828 ua->send_msg(_("Where: %s\n"),
829 jcr->where?jcr->where:NPRT(job->RestoreWhere));
832 ua->send_msg(_("Replace: %s\n"
842 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
843 bstrutime(dt, sizeof(dt), jcr->sched_time),
844 jcr->catalog->name(),
849 jcr->JobLevel = L_FULL; /* default level */
850 if (ua->api) ua->signal(BNET_RUN_CMD);
851 ua->send_msg(_("Run Migration job\n"
856 "Pool: %s (From %s)\n"
857 "Read Storage: %s (From %s)\n"
858 "Write Storage: %s (From %s)\n"
864 NPRT(jcr->RestoreBootstrap),
866 jcr->fileset->name(),
867 NPRT(jcr->pool->name()), jcr->pool_source,
868 jcr->rstore->name(), jcr->rstore_source,
869 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
870 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
871 bstrutime(dt, sizeof(dt), jcr->sched_time),
872 jcr->catalog->name(),
876 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
883 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
887 static const char *kw[] = { /* command line arguments */
888 "job", /* Used in a switch() */
896 "regexwhere", /* 8 where string as a bregexp */
898 "bootstrap", /* 10 */
902 "yes", /* 14 -- if you change this change YES_POS too */
903 "verifyjob", /* 15 */
904 "files", /* 16 number of files to restore */
905 "catalog", /* 17 override catalog */
906 "since", /* 18 since */
907 "cloned", /* 19 cloned */
908 "verifylist", /* 20 verify output list */
909 "migrationjob", /* 21 migration job name */
911 "backupclient", /* 23 */
912 "restoreclient", /* 24 */
917 rc.catalog_name = NULL;
920 rc.store_name = NULL;
921 rc.client_name = NULL;
922 rc.restore_client_name = NULL;
923 rc.fileset_name = NULL;
924 rc.verify_job_name = NULL;
925 rc.previous_job_name = NULL;
928 for (i=1; i<ua->argc; i++) {
929 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
931 /* Keep looking until we find a good keyword */
932 for (j=0; !kw_ok && kw[j]; j++) {
933 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
934 /* Note, yes and run have no value, so do not fail */
935 if (!ua->argv[i] && j != YES_POS /*yes*/) {
936 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
939 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
943 ua->send_msg(_("Job name specified twice.\n"));
946 rc.job_name = ua->argv[i];
950 if (rc.jid && !rc.mod) {
951 ua->send_msg(_("JobId specified twice.\n"));
954 rc.jid = ua->argv[i];
959 if (rc.client_name) {
960 ua->send_msg(_("Client specified twice.\n"));
963 rc.client_name = ua->argv[i];
966 case 4: /* fileset */
967 if (rc.fileset_name) {
968 ua->send_msg(_("FileSet specified twice.\n"));
971 rc.fileset_name = ua->argv[i];
976 ua->send_msg(_("Level specified twice.\n"));
979 rc.level_name = ua->argv[i];
982 case 6: /* storage */
985 ua->send_msg(_("Storage specified twice.\n"));
988 rc.store_name = ua->argv[i];
991 case 8: /* regexwhere */
992 if ((rc.regexwhere || rc.where) && !rc.mod) {
993 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
996 rc.regexwhere = ua->argv[i];
997 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
998 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
1004 if ((rc.where || rc.regexwhere) && !rc.mod) {
1005 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
1008 rc.where = ua->argv[i];
1009 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
1010 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
1015 case 10: /* bootstrap */
1016 if (rc.bootstrap && !rc.mod) {
1017 ua->send_msg(_("Bootstrap specified twice.\n"));
1020 rc.bootstrap = ua->argv[i];
1023 case 11: /* replace */
1024 if (rc.replace && !rc.mod) {
1025 ua->send_msg(_("Replace specified twice.\n"));
1028 rc.replace = ua->argv[i];
1032 if (rc.when && !rc.mod) {
1033 ua->send_msg(_("When specified twice.\n"));
1036 rc.when = ua->argv[i];
1039 case 13: /* Priority */
1040 if (rc.Priority && !rc.mod) {
1041 ua->send_msg(_("Priority specified twice.\n"));
1044 rc.Priority = atoi(ua->argv[i]);
1045 if (rc.Priority <= 0) {
1046 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1054 case 15: /* Verify Job */
1055 if (rc.verify_job_name) {
1056 ua->send_msg(_("Verify Job specified twice.\n"));
1059 rc.verify_job_name = ua->argv[i];
1062 case 16: /* files */
1063 rc.files = atoi(ua->argv[i]);
1067 case 17: /* catalog */
1068 rc.catalog_name = ua->argv[i];
1072 case 18: /* since */
1073 rc.since = ua->argv[i];
1077 case 19: /* cloned */
1082 case 20: /* write verify list output */
1083 rc.verify_list = ua->argv[i];
1086 case 21: /* Migration Job */
1087 if (rc.previous_job_name) {
1088 ua->send_msg(_("Migration Job specified twice.\n"));
1091 rc.previous_job_name = ua->argv[i];
1096 ua->send_msg(_("Pool specified twice.\n"));
1099 rc.pool_name = ua->argv[i];
1102 case 23: /* backupclient */
1103 if (rc.client_name) {
1104 ua->send_msg(_("Client specified twice.\n"));
1107 rc.client_name = ua->argv[i];
1110 case 24: /* restoreclient */
1111 if (rc.restore_client_name && !rc.mod) {
1112 ua->send_msg(_("Restore Client specified twice.\n"));
1115 rc.restore_client_name = ua->argv[i];
1121 } /* end strcase compare */
1122 } /* end keyword loop */
1124 * End of keyword for loop -- if not found, we got a bogus keyword
1127 Dmsg1(800, "%s not found\n", ua->argk[i]);
1129 * Special case for Job Name, it can be the first
1130 * keyword that has no value.
1132 if (!rc.job_name && !ua->argv[i]) {
1133 rc.job_name = ua->argk[i]; /* use keyword as job name */
1134 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1136 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1140 } /* end argc loop */
1142 Dmsg0(800, "Done scan.\n");
1144 if (rc.catalog_name) {
1145 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1146 if (rc.catalog == NULL) {
1147 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1150 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1151 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1155 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1159 rc.job = GetJobResWithName(rc.job_name);
1161 if (*rc.job_name != 0) {
1162 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1164 rc.job = select_job_resource(ua);
1166 Dmsg1(800, "Found job=%s\n", rc.job_name);
1168 } else if (!rc.job) {
1169 ua->send_msg(_("A job name must be specified.\n"));
1170 rc.job = select_job_resource(ua);
1174 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1175 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1180 rc.pool = GetPoolResWithName(rc.pool_name);
1182 if (*rc.pool_name != 0) {
1183 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1185 rc.pool = select_pool_resource(ua);
1187 } else if (!rc.pool) {
1188 rc.pool = rc.job->pool; /* use default */
1192 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1193 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1196 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1198 if (rc.store_name) {
1199 rc.store->store = GetStoreResWithName(rc.store_name);
1200 pm_strcpy(rc.store->store_source, _("command line"));
1201 if (!rc.store->store) {
1202 if (*rc.store_name != 0) {
1203 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1205 rc.store->store = select_storage_resource(ua);
1206 pm_strcpy(rc.store->store_source, _("user selection"));
1208 } else if (!rc.store->store) {
1209 get_job_storage(rc.store, rc.job, NULL); /* use default */
1211 if (!rc.store->store) {
1212 ua->error_msg(_("No storage specified.\n"));
1214 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1215 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1216 rc.store->store->name());
1219 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1221 if (rc.client_name) {
1222 rc.client = GetClientResWithName(rc.client_name);
1224 if (*rc.client_name != 0) {
1225 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name);
1227 rc.client = select_client_resource(ua);
1229 } else if (!rc.client) {
1230 rc.client = rc.job->client; /* use default */
1234 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1235 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1239 Dmsg1(800, "Using client=%s\n", rc.client->name());
1241 if (rc.restore_client_name) {
1242 rc.client = GetClientResWithName(rc.restore_client_name);
1244 if (*rc.restore_client_name != 0) {
1245 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1247 rc.client = select_client_resource(ua);
1249 } else if (!rc.client) {
1250 rc.client = rc.job->client; /* use default */
1254 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1255 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1259 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1262 if (rc.fileset_name) {
1263 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1265 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1266 rc.fileset = select_fileset_resource(ua);
1268 } else if (!rc.fileset) {
1269 rc.fileset = rc.job->fileset; /* use default */
1273 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1274 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1275 rc.fileset->name());
1279 if (rc.verify_job_name) {
1280 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1281 if (!rc.verify_job) {
1282 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1283 rc.verify_job = select_job_resource(ua);
1285 } else if (!rc.verify_job) {
1286 rc.verify_job = rc.job->verify_job;
1289 if (rc.previous_job_name) {
1290 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1291 if (!rc.previous_job) {
1292 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1293 rc.previous_job = select_job_resource(ua);
1296 rc.previous_job = rc.job->verify_job;