2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- Run Command
32 * Kern Sibbald, December MMI
42 char *job_name, *level_name, *jid, *store_name, *pool_name;
43 char *where, *fileset_name, *client_name, *bootstrap, *regexwhere;
44 char *restore_client_name;
46 char *when, *verify_job_name, *catalog_name;
47 char *previous_job_name;
49 const char *verify_list;
64 run_ctx() { memset(this, 0, sizeof(run_ctx));
65 store = new USTORE; };
66 ~run_ctx() { delete store; };
69 /* Forward referenced subroutines */
70 static void select_job_level(UAContext *ua, JCR *jcr);
71 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job,
72 const char *verify_list, char *jid, const char *replace,
74 static void select_where_regexp(UAContext *ua, JCR *jcr);
75 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc);
77 /* Imported variables */
78 extern struct s_kw ReplaceOptions[];
81 * For Backup and Verify Jobs
82 * run [job=]<job-name> level=<level-name>
91 int run_cmd(UAContext *ua, const char *cmd)
97 if (!open_client_db(ua)) {
101 if (!scan_command_line_arguments(ua, rc)) {
105 if (find_arg(ua, NT_("fdcalled")) > 0) {
106 jcr->file_bsock = dup_bsock(ua->UA_sock);
112 * Create JCR to run job. NOTE!!! after this point, free_jcr()
116 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
117 set_jcr_defaults(jcr, rc.job);
118 jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */
119 ua->jcr->unlink_bsr = false;
122 jcr->verify_job = rc.verify_job;
123 jcr->previous_job = rc.previous_job;
125 set_rwstorage(jcr, rc.store);
126 jcr->client = rc.client;
127 pm_strcpy(jcr->client_name, rc.client->name());
128 jcr->fileset = rc.fileset;
129 jcr->ExpectedFiles = rc.files;
131 jcr->catalog = rc.catalog;
137 jcr->where = bstrdup(rc.where);
142 if (jcr->RegexWhere) {
143 free(jcr->RegexWhere);
145 jcr->RegexWhere = bstrdup(rc.regexwhere);
146 rc.regexwhere = NULL;
150 jcr->sched_time = str_to_utime(rc.when);
151 if (jcr->sched_time == 0) {
152 ua->send_msg(_("Invalid time, using current time.\n"));
153 jcr->sched_time = time(NULL);
159 if (jcr->RestoreBootstrap) {
160 free(jcr->RestoreBootstrap);
162 jcr->RestoreBootstrap = bstrdup(rc.bootstrap);
168 for (i=0; ReplaceOptions[i].name; i++) {
169 if (strcasecmp(rc.replace, ReplaceOptions[i].name) == 0) {
170 jcr->replace = ReplaceOptions[i].token;
174 ua->send_msg(_("Invalid replace option: %s\n"), rc.replace);
177 } else if (rc.job->replace) {
178 jcr->replace = rc.job->replace;
180 jcr->replace = REPLACE_ALWAYS;
185 jcr->JobPriority = rc.Priority;
191 jcr->stime = get_pool_memory(PM_MESSAGE);
193 pm_strcpy(jcr->stime, rc.since);
198 jcr->cloned = rc.cloned;
203 /* If pool changed, update migration write storage */
204 if (jcr->JobType == JT_MIGRATE) {
205 if (!set_migration_wstorage(jcr, rc.pool)) {
209 rc.replace = ReplaceOptions[0].name;
210 for (i=0; ReplaceOptions[i].name; i++) {
211 if (ReplaceOptions[i].token == jcr->replace) {
212 rc.replace = ReplaceOptions[i].name;
216 if (!get_level_from_name(jcr, rc.level_name)) {
217 ua->send_msg(_("Level %s not valid.\n"), rc.level_name);
220 rc.level_name = NULL;
223 /* Note, this is also MigrateJobId */
224 jcr->RestoreJobId = str_to_int64(rc.jid);
228 /* Run without prompting? */
229 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
234 * Prompt User to see if all run job parameters are correct, and
235 * allow him to modify them.
237 if (!display_job_parameters(ua, jcr, rc.job, rc.verify_list, rc.jid, rc.replace,
242 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
246 if (strncasecmp(ua->cmd, ".mod ", 5) == 0 ||
247 (strncasecmp(ua->cmd, "mod ", 4) == 0 && strlen(ua->cmd) > 6)) {
250 if (!scan_command_line_arguments(ua, rc)) {
257 * At user request modify parameters of job to be run.
259 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
262 start_prompt(ua, _("Parameters to modify:\n"));
263 add_prompt(ua, _("Level")); /* 0 */
264 add_prompt(ua, _("Storage")); /* 1 */
265 add_prompt(ua, _("Job")); /* 2 */
266 add_prompt(ua, _("FileSet")); /* 3 */
267 if (jcr->JobType == JT_RESTORE) {
268 add_prompt(ua, _("Restore Client")); /* 4 */
270 add_prompt(ua, _("Client")); /* 4 */
272 add_prompt(ua, _("When")); /* 5 */
273 add_prompt(ua, _("Priority")); /* 6 */
274 if (jcr->JobType == JT_BACKUP ||
275 jcr->JobType == JT_MIGRATE ||
276 jcr->JobType == JT_VERIFY) {
277 add_prompt(ua, _("Pool")); /* 7 */
278 if (jcr->JobType == JT_VERIFY) {
279 add_prompt(ua, _("Verify Job")); /* 8 */
281 } else if (jcr->JobType == JT_RESTORE) {
282 add_prompt(ua, _("Bootstrap")); /* 7 */
283 add_prompt(ua, _("Where")); /* 8 */
284 add_prompt(ua, _("File Relocation"));/* 9 */
285 add_prompt(ua, _("Replace")); /* 10 */
286 add_prompt(ua, _("JobId")); /* 11 */
288 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
291 select_job_level(ua, jcr);
295 rc.store->store = select_storage_resource(ua);
296 if (rc.store->store) {
297 pm_strcpy(rc.store->store_source, _("user selection"));
298 set_rwstorage(jcr, rc.store);
304 rc.job = select_job_resource(ua);
307 set_jcr_defaults(jcr, rc.job);
313 rc.fileset = select_fileset_resource(ua);
315 jcr->fileset = rc.fileset;
321 rc.client = select_client_resource(ua);
323 jcr->client = rc.client;
329 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
332 if (ua->cmd[0] == 0) {
333 jcr->sched_time = time(NULL);
335 jcr->sched_time = str_to_utime(ua->cmd);
336 if (jcr->sched_time == 0) {
337 ua->send_msg(_("Invalid time, using current time.\n"));
338 jcr->sched_time = time(NULL);
344 if (!get_pint(ua, _("Enter new Priority: "))) {
347 if (ua->pint32_val == 0) {
348 ua->send_msg(_("Priority must be a positive integer.\n"));
350 jcr->JobPriority = ua->pint32_val;
354 /* Pool or Bootstrap depending on JobType */
355 if (jcr->JobType == JT_BACKUP ||
356 jcr->JobType == JT_MIGRATE ||
357 jcr->JobType == JT_VERIFY) { /* Pool */
358 rc.pool = select_pool_resource(ua);
361 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
368 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
371 if (jcr->RestoreBootstrap) {
372 free(jcr->RestoreBootstrap);
373 jcr->RestoreBootstrap = NULL;
375 if (ua->cmd[0] != 0) {
376 jcr->RestoreBootstrap = bstrdup(ua->cmd);
377 fd = fopen(jcr->RestoreBootstrap, "rb");
380 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
381 jcr->RestoreBootstrap, be.bstrerror());
382 free(jcr->RestoreBootstrap);
383 jcr->RestoreBootstrap = NULL;
391 if (jcr->JobType == JT_VERIFY) {
392 rc.verify_job = select_job_resource(ua);
394 jcr->verify_job = rc.verify_job;
399 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
402 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
403 free(jcr->RegexWhere);
404 jcr->RegexWhere = NULL;
410 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
413 jcr->where = bstrdup(ua->cmd);
416 /* File relocation */
417 select_where_regexp(ua, jcr);
421 start_prompt(ua, _("Replace:\n"));
422 for (i=0; ReplaceOptions[i].name; i++) {
423 add_prompt(ua, ReplaceOptions[i].name);
425 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
427 rc.replace = ReplaceOptions[opt].name;
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 Dmsg3(100, "JobId=%u using pool %s priority=%d\n", (int)jcr->JobId,
453 jcr->pool->name(), jcr->JobPriority);
454 JobId = run_job(jcr);
455 Dmsg4(100, "JobId=%u NewJobId=%d using pool %s priority=%d\n", (int)jcr->JobId,
456 JobId, jcr->pool->name(), jcr->JobPriority);
457 free_jcr(jcr); /* release jcr */
459 ua->error_msg(_("Job failed.\n"));
462 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
468 ua->send_msg(_("Job not run.\n"));
470 return 0; /* do not run */
473 static void select_where_regexp(UAContext *ua, JCR *jcr)
476 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
477 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
480 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
481 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
483 start_prompt(ua, _("This will replace your current Where value\n"));
484 add_prompt(ua, _("Strip prefix")); /* 0 */
485 add_prompt(ua, _("Add prefix")); /* 1 */
486 add_prompt(ua, _("Add file suffix")); /* 2 */
487 add_prompt(ua, _("Enter a regexp")); /* 3 */
488 add_prompt(ua, _("Test filename manipulation")); /* 4 */
489 add_prompt(ua, _("Use this ?")); /* 5 */
491 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
494 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
495 if (strip_prefix) bfree(strip_prefix);
496 strip_prefix = bstrdup(ua->cmd);
502 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
503 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
507 if (add_prefix) bfree(add_prefix);
508 add_prefix = bstrdup(ua->cmd);
513 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
514 if (add_suffix) bfree(add_suffix);
515 add_suffix = bstrdup(ua->cmd);
520 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
521 if (rwhere) bfree(rwhere);
522 rwhere = bstrdup(ua->cmd);
531 if (rwhere && rwhere[0] != '\0') {
532 regs = get_bregexps(rwhere);
533 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
535 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
536 regexp = (char *) bmalloc (len * sizeof(char));
537 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
538 regs = get_bregexps(regexp);
539 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
540 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
546 ua->send_msg(_("Cannot use your regexp\n"));
550 while (get_cmd(ua, _("Please enter filename to test: "))) {
551 apply_bregexps(ua->cmd, regs, &result);
552 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
561 case -1: /* error or cancel */
567 /* replace the existing where */
573 /* replace the existing regexwhere */
574 if (jcr->RegexWhere) {
575 bfree(jcr->RegexWhere);
576 jcr->RegexWhere = NULL;
580 jcr->RegexWhere = bstrdup(rwhere);
581 } else if (strip_prefix || add_prefix || add_suffix) {
582 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
583 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
584 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
587 regs = get_bregexps(jcr->RegexWhere);
592 if (jcr->RegexWhere) {
593 bfree(jcr->RegexWhere);
594 jcr->RegexWhere = NULL;
596 ua->send_msg(_("Cannot use your regexp.\n"));
600 if (strip_prefix) bfree(strip_prefix);
601 if (add_prefix) bfree(add_prefix);
602 if (add_suffix) bfree(add_suffix);
603 if (rwhere) bfree(rwhere);
606 static void select_job_level(UAContext *ua, JCR *jcr)
608 if (jcr->JobType == JT_BACKUP) {
609 start_prompt(ua, _("Levels:\n"));
610 add_prompt(ua, _("Base"));
611 add_prompt(ua, _("Full"));
612 add_prompt(ua, _("Incremental"));
613 add_prompt(ua, _("Differential"));
614 add_prompt(ua, _("Since"));
615 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
617 jcr->JobLevel = L_BASE;
620 jcr->JobLevel = L_FULL;
623 jcr->JobLevel = L_INCREMENTAL;
626 jcr->JobLevel = L_DIFFERENTIAL;
629 jcr->JobLevel = L_SINCE;
634 } else if (jcr->JobType == JT_VERIFY) {
635 start_prompt(ua, _("Levels:\n"));
636 add_prompt(ua, _("Initialize Catalog"));
637 add_prompt(ua, _("Verify Catalog"));
638 add_prompt(ua, _("Verify Volume to Catalog"));
639 add_prompt(ua, _("Verify Disk to Catalog"));
640 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
641 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
643 jcr->JobLevel = L_VERIFY_INIT;
646 jcr->JobLevel = L_VERIFY_CATALOG;
649 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
652 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
655 jcr->JobLevel = L_VERIFY_DATA;
661 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
666 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, const char *verify_list,
667 char *jid, const char *replace, char *client_name)
669 Dmsg1(800, "JobType=%c\n", jcr->JobType);
670 switch (jcr->JobType) {
672 char dt[MAX_TIME_LENGTH];
674 if (ua->api) ua->signal(BNET_RUN_CMD);
675 ua->send_msg(_("Run %s job\n"
684 jcr->fileset->name(),
685 NPRT(jcr->client->name()),
686 jcr->wstore?jcr->wstore->name():"*None*",
687 bstrutime(dt, sizeof(dt), jcr->sched_time),
689 jcr->JobLevel = L_FULL;
693 if (jcr->JobType == JT_BACKUP) {
694 if (ua->api) ua->signal(BNET_RUN_CMD);
695 ua->send_msg(_("Run %s job\n"
700 "Pool: %s (From %s)\n"
701 "Storage: %s (From %s)\n"
706 level_to_str(jcr->JobLevel),
708 jcr->fileset->name(),
709 NPRT(jcr->pool->name()), jcr->pool_source,
710 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
711 bstrutime(dt, sizeof(dt), jcr->sched_time),
713 } else { /* JT_VERIFY */
715 if (jcr->verify_job) {
716 Name = jcr->verify_job->name();
721 verify_list = job->WriteVerifyList;
726 if (ua->api) ua->signal(BNET_RUN_CMD);
727 ua->send_msg(_("Run %s job\n"
732 "Pool: %s (From %s)\n"
733 "Storage: %s (From %s)\n"
740 level_to_str(jcr->JobLevel),
742 jcr->fileset->name(),
743 NPRT(jcr->pool->name()), jcr->pool_source,
744 jcr->rstore->name(), jcr->rstore_source,
747 bstrutime(dt, sizeof(dt), jcr->sched_time),
752 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
754 jcr->RestoreJobId = str_to_int64(jid);
756 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
759 jcr->RestoreJobId = ua->int64_val;
762 jcr->JobLevel = L_FULL; /* default level */
763 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
764 if (jcr->RestoreJobId == 0) {
765 if (ua->api) ua->signal(BNET_RUN_CMD);
766 /* RegexWhere is take before RestoreWhere */
767 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
768 ua->send_msg(_("Run Restore job\n"
774 "Backup Client: %s\n"
775 "Restore Client: %s\n"
781 NPRT(jcr->RestoreBootstrap),
782 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
784 jcr->fileset->name(),
788 bstrutime(dt, sizeof(dt), jcr->sched_time),
789 jcr->catalog->name(),
793 ua->send_msg(_("Run Restore job\n"
799 "Backup Client: %s\n"
800 "Restore Client: %s\n"
806 NPRT(jcr->RestoreBootstrap),
807 jcr->where?jcr->where:NPRT(job->RestoreWhere),
809 jcr->fileset->name(),
813 bstrutime(dt, sizeof(dt), jcr->sched_time),
814 jcr->catalog->name(),
819 if (ua->api) ua->signal(BNET_RUN_CMD);
820 ua->send_msg(_("Run Restore job\n"
824 NPRT(jcr->RestoreBootstrap));
826 /* RegexWhere is take before RestoreWhere */
827 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
828 ua->send_msg(_("RegexWhere: %s\n"),
829 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
831 ua->send_msg(_("Where: %s\n"),
832 jcr->where?jcr->where:NPRT(job->RestoreWhere));
835 ua->send_msg(_("Replace: %s\n"
845 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
846 bstrutime(dt, sizeof(dt), jcr->sched_time),
847 jcr->catalog->name(),
852 jcr->JobLevel = L_FULL; /* default level */
853 if (ua->api) ua->signal(BNET_RUN_CMD);
854 ua->send_msg(_("Run Migration job\n"
859 "Pool: %s (From %s)\n"
860 "Read Storage: %s (From %s)\n"
861 "Write Storage: %s (From %s)\n"
867 NPRT(jcr->RestoreBootstrap),
869 jcr->fileset->name(),
870 NPRT(jcr->pool->name()), jcr->pool_source,
871 jcr->rstore->name(), jcr->rstore_source,
872 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
873 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
874 bstrutime(dt, sizeof(dt), jcr->sched_time),
875 jcr->catalog->name(),
879 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
886 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
890 static const char *kw[] = { /* command line arguments */
891 "job", /* Used in a switch() */
899 "regexwhere", /* 8 where string as a bregexp */
901 "bootstrap", /* 10 */
905 "yes", /* 14 -- if you change this change YES_POS too */
906 "verifyjob", /* 15 */
907 "files", /* 16 number of files to restore */
908 "catalog", /* 17 override catalog */
909 "since", /* 18 since */
910 "cloned", /* 19 cloned */
911 "verifylist", /* 20 verify output list */
912 "migrationjob", /* 21 migration job name */
914 "backupclient", /* 23 */
915 "restoreclient", /* 24 */
920 rc.catalog_name = NULL;
923 rc.store_name = NULL;
924 rc.client_name = NULL;
925 rc.restore_client_name = NULL;
926 rc.fileset_name = NULL;
927 rc.verify_job_name = NULL;
928 rc.previous_job_name = NULL;
931 for (i=1; i<ua->argc; i++) {
932 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
934 /* Keep looking until we find a good keyword */
935 for (j=0; !kw_ok && kw[j]; j++) {
936 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
937 /* Note, yes and run have no value, so do not fail */
938 if (!ua->argv[i] && j != YES_POS /*yes*/) {
939 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
942 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
946 ua->send_msg(_("Job name specified twice.\n"));
949 rc.job_name = ua->argv[i];
953 if (rc.jid && !rc.mod) {
954 ua->send_msg(_("JobId specified twice.\n"));
957 rc.jid = ua->argv[i];
962 if (rc.client_name) {
963 ua->send_msg(_("Client specified twice.\n"));
966 rc.client_name = ua->argv[i];
969 case 4: /* fileset */
970 if (rc.fileset_name) {
971 ua->send_msg(_("FileSet specified twice.\n"));
974 rc.fileset_name = ua->argv[i];
979 ua->send_msg(_("Level specified twice.\n"));
982 rc.level_name = ua->argv[i];
985 case 6: /* storage */
988 ua->send_msg(_("Storage specified twice.\n"));
991 rc.store_name = ua->argv[i];
994 case 8: /* regexwhere */
995 if ((rc.regexwhere || rc.where) && !rc.mod) {
996 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
999 rc.regexwhere = ua->argv[i];
1000 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
1001 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
1007 if ((rc.where || rc.regexwhere) && !rc.mod) {
1008 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
1011 rc.where = ua->argv[i];
1012 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
1013 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
1018 case 10: /* bootstrap */
1019 if (rc.bootstrap && !rc.mod) {
1020 ua->send_msg(_("Bootstrap specified twice.\n"));
1023 rc.bootstrap = ua->argv[i];
1026 case 11: /* replace */
1027 if (rc.replace && !rc.mod) {
1028 ua->send_msg(_("Replace specified twice.\n"));
1031 rc.replace = ua->argv[i];
1035 if (rc.when && !rc.mod) {
1036 ua->send_msg(_("When specified twice.\n"));
1039 rc.when = ua->argv[i];
1042 case 13: /* Priority */
1043 if (rc.Priority && !rc.mod) {
1044 ua->send_msg(_("Priority specified twice.\n"));
1047 rc.Priority = atoi(ua->argv[i]);
1048 if (rc.Priority <= 0) {
1049 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1057 case 15: /* Verify Job */
1058 if (rc.verify_job_name) {
1059 ua->send_msg(_("Verify Job specified twice.\n"));
1062 rc.verify_job_name = ua->argv[i];
1065 case 16: /* files */
1066 rc.files = atoi(ua->argv[i]);
1070 case 17: /* catalog */
1071 rc.catalog_name = ua->argv[i];
1075 case 18: /* since */
1076 rc.since = ua->argv[i];
1080 case 19: /* cloned */
1085 case 20: /* write verify list output */
1086 rc.verify_list = ua->argv[i];
1089 case 21: /* Migration Job */
1090 if (rc.previous_job_name) {
1091 ua->send_msg(_("Migration Job specified twice.\n"));
1094 rc.previous_job_name = ua->argv[i];
1099 ua->send_msg(_("Pool specified twice.\n"));
1102 rc.pool_name = ua->argv[i];
1105 case 23: /* backupclient */
1106 if (rc.client_name) {
1107 ua->send_msg(_("Client specified twice.\n"));
1110 rc.client_name = ua->argv[i];
1113 case 24: /* restoreclient */
1114 if (rc.restore_client_name && !rc.mod) {
1115 ua->send_msg(_("Restore Client specified twice.\n"));
1118 rc.restore_client_name = ua->argv[i];
1124 } /* end strcase compare */
1125 } /* end keyword loop */
1127 * End of keyword for loop -- if not found, we got a bogus keyword
1130 Dmsg1(800, "%s not found\n", ua->argk[i]);
1132 * Special case for Job Name, it can be the first
1133 * keyword that has no value.
1135 if (!rc.job_name && !ua->argv[i]) {
1136 rc.job_name = ua->argk[i]; /* use keyword as job name */
1137 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1139 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1143 } /* end argc loop */
1145 Dmsg0(800, "Done scan.\n");
1147 if (rc.catalog_name) {
1148 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1149 if (rc.catalog == NULL) {
1150 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1153 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1154 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1158 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1162 rc.job = GetJobResWithName(rc.job_name);
1164 if (*rc.job_name != 0) {
1165 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1167 rc.job = select_job_resource(ua);
1169 Dmsg1(800, "Found job=%s\n", rc.job_name);
1171 } else if (!rc.job) {
1172 ua->send_msg(_("A job name must be specified.\n"));
1173 rc.job = select_job_resource(ua);
1177 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1178 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1183 rc.pool = GetPoolResWithName(rc.pool_name);
1185 if (*rc.pool_name != 0) {
1186 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1188 rc.pool = select_pool_resource(ua);
1190 } else if (!rc.pool) {
1191 rc.pool = rc.job->pool; /* use default */
1195 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1196 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1199 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1201 if (rc.store_name) {
1202 rc.store->store = GetStoreResWithName(rc.store_name);
1203 pm_strcpy(rc.store->store_source, _("command line"));
1204 if (!rc.store->store) {
1205 if (*rc.store_name != 0) {
1206 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1208 rc.store->store = select_storage_resource(ua);
1209 pm_strcpy(rc.store->store_source, _("user selection"));
1211 } else if (!rc.store->store) {
1212 get_job_storage(rc.store, rc.job, NULL); /* use default */
1214 if (!rc.store->store) {
1215 ua->error_msg(_("No storage specified.\n"));
1217 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1218 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1219 rc.store->store->name());
1222 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1224 if (rc.client_name) {
1225 rc.client = GetClientResWithName(rc.client_name);
1227 if (*rc.client_name != 0) {
1228 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.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 client=%s\n", rc.client->name());
1244 if (rc.restore_client_name) {
1245 rc.client = GetClientResWithName(rc.restore_client_name);
1247 if (*rc.restore_client_name != 0) {
1248 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1250 rc.client = select_client_resource(ua);
1252 } else if (!rc.client) {
1253 rc.client = rc.job->client; /* use default */
1257 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1258 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1262 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1265 if (rc.fileset_name) {
1266 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1268 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1269 rc.fileset = select_fileset_resource(ua);
1271 } else if (!rc.fileset) {
1272 rc.fileset = rc.job->fileset; /* use default */
1276 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1277 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1278 rc.fileset->name());
1282 if (rc.verify_job_name) {
1283 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1284 if (!rc.verify_job) {
1285 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1286 rc.verify_job = select_job_resource(ua);
1288 } else if (!rc.verify_job) {
1289 rc.verify_job = rc.job->verify_job;
1292 if (rc.previous_job_name) {
1293 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1294 if (!rc.previous_job) {
1295 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1296 rc.previous_job = select_job_resource(ua);
1299 rc.previous_job = rc.job->verify_job;