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)) {
106 * Create JCR to run job. NOTE!!! after this point, free_jcr()
109 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
110 set_jcr_defaults(jcr, rc.job);
111 jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */
112 ua->jcr->unlink_bsr = false;
114 jcr->verify_job = rc.verify_job;
115 jcr->previous_job = rc.previous_job;
117 set_rwstorage(jcr, rc.store);
118 jcr->client = rc.client;
119 pm_strcpy(jcr->client_name, rc.client->name());
120 jcr->fileset = rc.fileset;
121 jcr->ExpectedFiles = rc.files;
122 if (rc.catalog != NULL) {
123 jcr->catalog = rc.catalog;
129 jcr->where = bstrdup(rc.where);
133 if (jcr->RegexWhere) {
134 free(jcr->RegexWhere);
136 jcr->RegexWhere = bstrdup(rc.regexwhere);
140 jcr->sched_time = str_to_utime(rc.when);
141 if (jcr->sched_time == 0) {
142 ua->send_msg(_("Invalid time, using current time.\n"));
143 jcr->sched_time = time(NULL);
148 if (jcr->RestoreBootstrap) {
149 free(jcr->RestoreBootstrap);
151 jcr->RestoreBootstrap = bstrdup(rc.bootstrap);
156 for (i=0; ReplaceOptions[i].name; i++) {
157 if (strcasecmp(rc.replace, ReplaceOptions[i].name) == 0) {
158 jcr->replace = ReplaceOptions[i].token;
162 ua->send_msg(_("Invalid replace option: %s\n"), rc.replace);
165 } else if (rc.job->replace) {
166 jcr->replace = rc.job->replace;
168 jcr->replace = REPLACE_ALWAYS;
172 jcr->JobPriority = rc.Priority;
177 jcr->stime = get_pool_memory(PM_MESSAGE);
179 pm_strcpy(jcr->stime, rc.since);
182 jcr->cloned = rc.cloned;
184 if (find_arg(ua, NT_("fdcalled")) > 0) {
185 jcr->file_bsock = dup_bsock(ua->UA_sock);
190 /* If pool changed, update migration write storage */
191 if (jcr->JobType == JT_MIGRATE) {
192 if (!set_migration_wstorage(jcr, rc.pool)) {
196 rc.replace = ReplaceOptions[0].name;
197 for (i=0; ReplaceOptions[i].name; i++) {
198 if (ReplaceOptions[i].token == jcr->replace) {
199 rc.replace = ReplaceOptions[i].name;
203 if (!get_level_from_name(jcr, rc.level_name)) {
204 ua->send_msg(_("Level %s not valid.\n"), rc.level_name);
209 /* Note, this is also MigrateJobId */
210 jcr->RestoreJobId = str_to_int64(rc.jid);
213 /* Run without prompting? */
214 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
219 * Prompt User to see if all run job parameters are correct, and
220 * allow him to modify them.
222 if (!display_job_parameters(ua, jcr, rc.job, rc.verify_list, rc.jid, rc.replace,
227 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
231 if (ua->cmd[0] == '.' && strncasecmp(ua->cmd, ".mod ", 5) == 0) {
232 Dmsg1(000, "got: %s\n", ua->cmd);
235 if (!scan_command_line_arguments(ua, rc)) {
242 * At user request modify parameters of job to be run.
244 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
247 start_prompt(ua, _("Parameters to modify:\n"));
248 add_prompt(ua, _("Level")); /* 0 */
249 add_prompt(ua, _("Storage")); /* 1 */
250 add_prompt(ua, _("Job")); /* 2 */
251 add_prompt(ua, _("FileSet")); /* 3 */
252 if (jcr->JobType == JT_RESTORE) {
253 add_prompt(ua, _("Restore Client")); /* 4 */
255 add_prompt(ua, _("Client")); /* 4 */
257 add_prompt(ua, _("When")); /* 5 */
258 add_prompt(ua, _("Priority")); /* 6 */
259 if (jcr->JobType == JT_BACKUP ||
260 jcr->JobType == JT_MIGRATE ||
261 jcr->JobType == JT_VERIFY) {
262 add_prompt(ua, _("Pool")); /* 7 */
263 if (jcr->JobType == JT_VERIFY) {
264 add_prompt(ua, _("Verify Job")); /* 8 */
266 } else if (jcr->JobType == JT_RESTORE) {
267 add_prompt(ua, _("Bootstrap")); /* 7 */
268 add_prompt(ua, _("Where")); /* 8 */
269 add_prompt(ua, _("File Relocation"));/* 9 */
270 add_prompt(ua, _("Replace")); /* 10 */
271 add_prompt(ua, _("JobId")); /* 11 */
273 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
276 select_job_level(ua, jcr);
280 rc.store->store = select_storage_resource(ua);
281 if (rc.store->store) {
282 pm_strcpy(rc.store->store_source, _("user selection"));
283 set_rwstorage(jcr, rc.store);
289 rc.job = select_job_resource(ua);
292 set_jcr_defaults(jcr, rc.job);
298 rc.fileset = select_fileset_resource(ua);
300 jcr->fileset = rc.fileset;
306 rc.client = select_client_resource(ua);
308 jcr->client = rc.client;
314 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
317 if (ua->cmd[0] == 0) {
318 jcr->sched_time = time(NULL);
320 jcr->sched_time = str_to_utime(ua->cmd);
321 if (jcr->sched_time == 0) {
322 ua->send_msg(_("Invalid time, using current time.\n"));
323 jcr->sched_time = time(NULL);
329 if (!get_pint(ua, _("Enter new Priority: "))) {
332 if (ua->pint32_val == 0) {
333 ua->send_msg(_("Priority must be a positive integer.\n"));
335 jcr->JobPriority = ua->pint32_val;
339 /* Pool or Bootstrap depending on JobType */
340 if (jcr->JobType == JT_BACKUP ||
341 jcr->JobType == JT_MIGRATE ||
342 jcr->JobType == JT_VERIFY) { /* Pool */
343 rc.pool = select_pool_resource(ua);
346 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
353 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
356 if (jcr->RestoreBootstrap) {
357 free(jcr->RestoreBootstrap);
358 jcr->RestoreBootstrap = NULL;
360 if (ua->cmd[0] != 0) {
361 jcr->RestoreBootstrap = bstrdup(ua->cmd);
362 fd = fopen(jcr->RestoreBootstrap, "rb");
364 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
365 jcr->RestoreBootstrap, strerror(errno));
366 free(jcr->RestoreBootstrap);
367 jcr->RestoreBootstrap = NULL;
375 if (jcr->JobType == JT_VERIFY) {
376 rc.verify_job = select_job_resource(ua);
378 jcr->verify_job = rc.verify_job;
383 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
386 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
387 free(jcr->RegexWhere);
388 jcr->RegexWhere = NULL;
394 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
397 jcr->where = bstrdup(ua->cmd);
400 /* File relocation */
401 select_where_regexp(ua, jcr);
405 start_prompt(ua, _("Replace:\n"));
406 for (i=0; ReplaceOptions[i].name; i++) {
407 add_prompt(ua, ReplaceOptions[i].name);
409 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
411 jcr->replace = ReplaceOptions[opt].token;
416 rc.jid = NULL; /* force reprompt */
417 jcr->RestoreJobId = 0;
418 if (jcr->RestoreBootstrap) {
419 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
422 case -1: /* error or cancel */
430 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
432 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
435 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
436 JobId = run_job(jcr);
437 free_jcr(jcr); /* release jcr */
439 ua->error_msg(_("Job failed.\n"));
442 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
448 ua->send_msg(_("Job not run.\n"));
450 return 0; /* do not run */
453 static void select_where_regexp(UAContext *ua, JCR *jcr)
456 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
457 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
460 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
461 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
463 start_prompt(ua, _("This will replace your current Where value\n"));
464 add_prompt(ua, _("Strip prefix")); /* 0 */
465 add_prompt(ua, _("Add prefix")); /* 1 */
466 add_prompt(ua, _("Add file suffix")); /* 2 */
467 add_prompt(ua, _("Enter a regexp")); /* 3 */
468 add_prompt(ua, _("Test filename manipulation")); /* 4 */
469 add_prompt(ua, _("Use this ?")); /* 5 */
471 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
474 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
475 if (strip_prefix) bfree(strip_prefix);
476 strip_prefix = bstrdup(ua->cmd);
482 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
483 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
487 if (add_prefix) bfree(add_prefix);
488 add_prefix = bstrdup(ua->cmd);
493 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
494 if (add_suffix) bfree(add_suffix);
495 add_suffix = bstrdup(ua->cmd);
500 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
501 if (rwhere) bfree(rwhere);
502 rwhere = bstrdup(ua->cmd);
511 if (rwhere && rwhere[0] != '\0') {
512 regs = get_bregexps(rwhere);
513 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
515 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
516 regexp = (char *) bmalloc (len * sizeof(char));
517 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
518 regs = get_bregexps(regexp);
519 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
520 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
526 ua->send_msg(_("Cannot use your regexp\n"));
530 while (get_cmd(ua, _("Please enter filename to test: "))) {
531 apply_bregexps(ua->cmd, regs, &result);
532 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
541 case -1: /* error or cancel */
547 /* replace the existing where */
553 /* replace the existing regexwhere */
554 if (jcr->RegexWhere) {
555 bfree(jcr->RegexWhere);
556 jcr->RegexWhere = NULL;
560 jcr->RegexWhere = bstrdup(rwhere);
561 } else if (strip_prefix || add_prefix || add_suffix) {
562 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
563 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
564 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
567 regs = get_bregexps(jcr->RegexWhere);
572 if (jcr->RegexWhere) {
573 bfree(jcr->RegexWhere);
574 jcr->RegexWhere = NULL;
576 ua->send_msg(_("Cannot use your regexp.\n"));
580 if (strip_prefix) bfree(strip_prefix);
581 if (add_prefix) bfree(add_prefix);
582 if (add_suffix) bfree(add_suffix);
583 if (rwhere) bfree(rwhere);
586 static void select_job_level(UAContext *ua, JCR *jcr)
588 if (jcr->JobType == JT_BACKUP) {
589 start_prompt(ua, _("Levels:\n"));
590 add_prompt(ua, _("Base"));
591 add_prompt(ua, _("Full"));
592 add_prompt(ua, _("Incremental"));
593 add_prompt(ua, _("Differential"));
594 add_prompt(ua, _("Since"));
595 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
597 jcr->JobLevel = L_BASE;
600 jcr->JobLevel = L_FULL;
603 jcr->JobLevel = L_INCREMENTAL;
606 jcr->JobLevel = L_DIFFERENTIAL;
609 jcr->JobLevel = L_SINCE;
614 } else if (jcr->JobType == JT_VERIFY) {
615 start_prompt(ua, _("Levels:\n"));
616 add_prompt(ua, _("Initialize Catalog"));
617 add_prompt(ua, _("Verify Catalog"));
618 add_prompt(ua, _("Verify Volume to Catalog"));
619 add_prompt(ua, _("Verify Disk to Catalog"));
620 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
621 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
623 jcr->JobLevel = L_VERIFY_INIT;
626 jcr->JobLevel = L_VERIFY_CATALOG;
629 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
632 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
635 jcr->JobLevel = L_VERIFY_DATA;
641 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
646 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
647 char *jid, const char *replace, char *client_name)
649 Dmsg1(800, "JobType=%c\n", jcr->JobType);
650 switch (jcr->JobType) {
652 char dt[MAX_TIME_LENGTH];
654 if (ua->api) ua->signal(BNET_RUN_CMD);
655 ua->send_msg(_("Run %s job\n"
664 jcr->fileset->name(),
665 NPRT(jcr->client->name()),
666 jcr->wstore?jcr->wstore->name():"*None*",
667 bstrutime(dt, sizeof(dt), jcr->sched_time),
669 jcr->JobLevel = L_FULL;
673 if (jcr->JobType == JT_BACKUP) {
674 if (ua->api) ua->signal(BNET_RUN_CMD);
675 ua->send_msg(_("Run %s job\n"
680 "Pool: %s (From %s)\n"
681 "Storage: %s (From %s)\n"
686 level_to_str(jcr->JobLevel),
688 jcr->fileset->name(),
689 NPRT(jcr->pool->name()), jcr->pool_source,
690 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
691 bstrutime(dt, sizeof(dt), jcr->sched_time),
693 } else { /* JT_VERIFY */
695 if (jcr->verify_job) {
696 Name = jcr->verify_job->name();
701 verify_list = job->WriteVerifyList;
706 if (ua->api) ua->signal(BNET_RUN_CMD);
707 ua->send_msg(_("Run %s job\n"
712 "Pool: %s (From %s)\n"
713 "Storage: %s (From %s)\n"
720 level_to_str(jcr->JobLevel),
722 jcr->fileset->name(),
723 NPRT(jcr->pool->name()), jcr->pool_source,
724 jcr->rstore->name(), jcr->rstore_source,
727 bstrutime(dt, sizeof(dt), jcr->sched_time),
732 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
734 jcr->RestoreJobId = str_to_int64(jid);
736 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
739 jcr->RestoreJobId = ua->int64_val;
742 jcr->JobLevel = L_FULL; /* default level */
743 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
744 if (jcr->RestoreJobId == 0) {
745 if (ua->api) ua->signal(BNET_RUN_CMD);
746 /* RegexWhere is take before RestoreWhere */
747 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
748 ua->send_msg(_("Run Restore job\n"
754 "Backup Client: %s\n"
755 "Restore Client: %s\n"
761 NPRT(jcr->RestoreBootstrap),
762 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
764 jcr->fileset->name(),
768 bstrutime(dt, sizeof(dt), jcr->sched_time),
769 jcr->catalog->name(),
773 ua->send_msg(_("Run Restore job\n"
779 "Backup Client: %s\n"
780 "Restore Client: %s\n"
786 NPRT(jcr->RestoreBootstrap),
787 jcr->where?jcr->where:NPRT(job->RestoreWhere),
789 jcr->fileset->name(),
793 bstrutime(dt, sizeof(dt), jcr->sched_time),
794 jcr->catalog->name(),
799 if (ua->api) ua->signal(BNET_RUN_CMD);
800 ua->send_msg(_("Run Restore job\n"
804 NPRT(jcr->RestoreBootstrap));
806 /* RegexWhere is take before RestoreWhere */
807 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
808 ua->send_msg(_("RegexWhere: %s\n"),
809 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
811 ua->send_msg(_("Where: %s\n"),
812 jcr->where?jcr->where:NPRT(job->RestoreWhere));
815 ua->send_msg(_("Replace: %s\n"
825 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
826 bstrutime(dt, sizeof(dt), jcr->sched_time),
827 jcr->catalog->name(),
832 jcr->JobLevel = L_FULL; /* default level */
833 if (ua->api) ua->signal(BNET_RUN_CMD);
834 ua->send_msg(_("Run Migration job\n"
839 "Pool: %s (From %s)\n"
840 "Read Storage: %s (From %s)\n"
841 "Write Storage: %s (From %s)\n"
847 NPRT(jcr->RestoreBootstrap),
849 jcr->fileset->name(),
850 NPRT(jcr->pool->name()), jcr->pool_source,
851 jcr->rstore->name(), jcr->rstore_source,
852 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
853 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
854 bstrutime(dt, sizeof(dt), jcr->sched_time),
855 jcr->catalog->name(),
859 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
866 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
870 static const char *kw[] = { /* command line arguments */
871 "job", /* Used in a switch() */
879 "regexwhere", /* 8 where string as a bregexp */
881 "bootstrap", /* 10 */
885 "yes", /* 14 -- if you change this change YES_POS too */
886 "verifyjob", /* 15 */
887 "files", /* 16 number of files to restore */
888 "catalog", /* 17 override catalog */
889 "since", /* 18 since */
890 "cloned", /* 19 cloned */
891 "verifylist", /* 20 verify output list */
892 "migrationjob", /* 21 migration job name */
894 "backupclient", /* 23 */
895 "restoreclient", /* 24 */
900 rc.catalog_name = NULL;
903 rc.store_name = NULL;
904 rc.client_name = NULL;
905 rc.restore_client_name = NULL;
906 rc.fileset_name = NULL;
907 rc.verify_job_name = NULL;
908 rc.previous_job_name = NULL;
911 for (i=1; i<ua->argc; i++) {
912 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
914 /* Keep looking until we find a good keyword */
915 for (j=0; !kw_ok && kw[j]; j++) {
916 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
917 /* Note, yes and run have no value, so do not fail */
918 if (!ua->argv[i] && j != YES_POS /*yes*/) {
919 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
922 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
926 ua->send_msg(_("Job name specified twice.\n"));
929 rc.job_name = ua->argv[i];
933 if (rc.jid && !rc.mod) {
934 ua->send_msg(_("JobId specified twice.\n"));
937 rc.jid = ua->argv[i];
942 if (rc.client_name) {
943 ua->send_msg(_("Client specified twice.\n"));
946 rc.client_name = ua->argv[i];
949 case 4: /* fileset */
950 if (rc.fileset_name) {
951 ua->send_msg(_("FileSet specified twice.\n"));
954 rc.fileset_name = ua->argv[i];
959 ua->send_msg(_("Level specified twice.\n"));
962 rc.level_name = ua->argv[i];
965 case 6: /* storage */
968 ua->send_msg(_("Storage specified twice.\n"));
971 rc.store_name = ua->argv[i];
974 case 8: /* regexwhere */
975 if ((rc.regexwhere || rc.where) && !rc.mod) {
976 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
979 rc.regexwhere = ua->argv[i];
980 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
981 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
987 if ((rc.where || rc.regexwhere) && !rc.mod) {
988 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
991 rc.where = ua->argv[i];
992 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
993 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
998 case 10: /* bootstrap */
999 if (rc.bootstrap && !rc.mod) {
1000 ua->send_msg(_("Bootstrap specified twice.\n"));
1003 rc.bootstrap = ua->argv[i];
1006 case 11: /* replace */
1007 if (rc.replace && !rc.mod) {
1008 ua->send_msg(_("Replace specified twice.\n"));
1011 rc.replace = ua->argv[i];
1015 if (rc.when && !rc.mod) {
1016 ua->send_msg(_("When specified twice.\n"));
1019 rc.when = ua->argv[i];
1022 case 13: /* Priority */
1023 if (rc.Priority && !rc.mod) {
1024 ua->send_msg(_("Priority specified twice.\n"));
1027 rc.Priority = atoi(ua->argv[i]);
1028 if (rc.Priority <= 0) {
1029 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1037 case 15: /* Verify Job */
1038 if (rc.verify_job_name) {
1039 ua->send_msg(_("Verify Job specified twice.\n"));
1042 rc.verify_job_name = ua->argv[i];
1045 case 16: /* files */
1046 rc.files = atoi(ua->argv[i]);
1050 case 17: /* catalog */
1051 rc.catalog_name = ua->argv[i];
1055 case 18: /* since */
1056 rc.since = ua->argv[i];
1060 case 19: /* cloned */
1065 case 20: /* write verify list output */
1066 rc.verify_list = ua->argv[i];
1069 case 21: /* Migration Job */
1070 if (rc.previous_job_name) {
1071 ua->send_msg(_("Migration Job specified twice.\n"));
1074 rc.previous_job_name = ua->argv[i];
1079 ua->send_msg(_("Pool specified twice.\n"));
1082 rc.pool_name = ua->argv[i];
1085 case 23: /* backupclient */
1086 if (rc.client_name) {
1087 ua->send_msg(_("Client specified twice.\n"));
1090 rc.client_name = ua->argv[i];
1093 case 24: /* restoreclient */
1094 if (rc.restore_client_name && !rc.mod) {
1095 ua->send_msg(_("Restore Client specified twice.\n"));
1098 rc.restore_client_name = ua->argv[i];
1104 } /* end strcase compare */
1105 } /* end keyword loop */
1107 * End of keyword for loop -- if not found, we got a bogus keyword
1110 Dmsg1(800, "%s not found\n", ua->argk[i]);
1112 * Special case for Job Name, it can be the first
1113 * keyword that has no value.
1115 if (!rc.job_name && !ua->argv[i]) {
1116 rc.job_name = ua->argk[i]; /* use keyword as job name */
1117 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1119 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1123 } /* end argc loop */
1125 Dmsg0(800, "Done scan.\n");
1127 if (rc.catalog_name) {
1128 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1129 if (rc.catalog == NULL) {
1130 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1133 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1134 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1138 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1142 rc.job = GetJobResWithName(rc.job_name);
1144 if (*rc.job_name != 0) {
1145 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1147 rc.job = select_job_resource(ua);
1149 Dmsg1(800, "Found job=%s\n", rc.job_name);
1151 } else if (!rc.job) {
1152 ua->send_msg(_("A job name must be specified.\n"));
1153 rc.job = select_job_resource(ua);
1157 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1158 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1163 rc.pool = GetPoolResWithName(rc.pool_name);
1165 if (*rc.pool_name != 0) {
1166 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1168 rc.pool = select_pool_resource(ua);
1170 } else if (!rc.pool) {
1171 rc.pool = rc.job->pool; /* use default */
1175 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1176 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1179 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1181 if (rc.store_name) {
1182 rc.store->store = GetStoreResWithName(rc.store_name);
1183 pm_strcpy(rc.store->store_source, _("command line"));
1184 if (!rc.store->store) {
1185 if (*rc.store_name != 0) {
1186 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1188 rc.store->store = select_storage_resource(ua);
1189 pm_strcpy(rc.store->store_source, _("user selection"));
1191 } else if (!rc.store->store) {
1192 get_job_storage(rc.store, rc.job, NULL); /* use default */
1194 if (!rc.store->store) {
1195 ua->error_msg(_("No storage specified.\n"));
1197 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1198 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1199 rc.store->store->name());
1202 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1204 if (rc.client_name) {
1205 rc.client = GetClientResWithName(rc.client_name);
1207 if (*rc.client_name != 0) {
1208 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name);
1210 rc.client = select_client_resource(ua);
1212 } else if (!rc.client) {
1213 rc.client = rc.job->client; /* use default */
1217 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1218 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1222 Dmsg1(800, "Using client=%s\n", rc.client->name());
1224 if (rc.restore_client_name) {
1225 rc.client = GetClientResWithName(rc.restore_client_name);
1227 if (*rc.restore_client_name != 0) {
1228 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1230 rc.client = select_client_resource(ua);
1232 } else if (!rc.client) {
1233 rc.client = rc.job->client; /* use default */
1237 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1238 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1242 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1245 if (rc.fileset_name) {
1246 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1248 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1249 rc.fileset = select_fileset_resource(ua);
1251 } else if (!rc.fileset) {
1252 rc.fileset = rc.job->fileset; /* use default */
1256 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1257 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1258 rc.fileset->name());
1262 if (rc.verify_job_name) {
1263 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1264 if (!rc.verify_job) {
1265 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1266 rc.verify_job = select_job_resource(ua);
1268 } else if (!rc.verify_job) {
1269 rc.verify_job = rc.job->verify_job;
1272 if (rc.previous_job_name) {
1273 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1274 if (!rc.previous_job) {
1275 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1276 rc.previous_job = select_job_resource(ua);
1279 rc.previous_job = rc.job->verify_job;