2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2008 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 if (jcr->pool != jcr->job->pool) {
126 pm_strcpy(jcr->pool_source, _("User input"));
128 set_rwstorage(jcr, rc.store);
129 jcr->client = rc.client;
130 pm_strcpy(jcr->client_name, rc.client->name());
131 jcr->fileset = rc.fileset;
132 jcr->ExpectedFiles = rc.files;
134 jcr->catalog = rc.catalog;
135 pm_strcpy(jcr->catalog_source, _("User input"));
141 jcr->where = bstrdup(rc.where);
146 if (jcr->RegexWhere) {
147 free(jcr->RegexWhere);
149 jcr->RegexWhere = bstrdup(rc.regexwhere);
150 rc.regexwhere = NULL;
154 jcr->sched_time = str_to_utime(rc.when);
155 if (jcr->sched_time == 0) {
156 ua->send_msg(_("Invalid time, using current time.\n"));
157 jcr->sched_time = time(NULL);
163 if (jcr->RestoreBootstrap) {
164 free(jcr->RestoreBootstrap);
166 jcr->RestoreBootstrap = bstrdup(rc.bootstrap);
172 for (i=0; ReplaceOptions[i].name; i++) {
173 if (strcasecmp(rc.replace, ReplaceOptions[i].name) == 0) {
174 jcr->replace = ReplaceOptions[i].token;
178 ua->send_msg(_("Invalid replace option: %s\n"), rc.replace);
181 } else if (rc.job->replace) {
182 jcr->replace = rc.job->replace;
184 jcr->replace = REPLACE_ALWAYS;
189 jcr->JobPriority = rc.Priority;
195 jcr->stime = get_pool_memory(PM_MESSAGE);
197 pm_strcpy(jcr->stime, rc.since);
202 jcr->cloned = rc.cloned;
207 /* If pool changed, update migration write storage */
208 if (jcr->JobType == JT_MIGRATE || jcr->JobType == JT_COPY) {
209 if (!set_migration_wstorage(jcr, rc.pool)) {
213 rc.replace = ReplaceOptions[0].name;
214 for (i=0; ReplaceOptions[i].name; i++) {
215 if (ReplaceOptions[i].token == jcr->replace) {
216 rc.replace = ReplaceOptions[i].name;
220 if (!get_level_from_name(jcr, rc.level_name)) {
221 ua->send_msg(_("Level %s not valid.\n"), rc.level_name);
224 rc.level_name = NULL;
227 /* Note, this is also MigrateJobId */
228 jcr->RestoreJobId = str_to_int64(rc.jid);
232 /* Run without prompting? */
233 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
238 * Prompt User to see if all run job parameters are correct, and
239 * allow him to modify them.
241 if (!display_job_parameters(ua, jcr, rc.job, rc.verify_list, rc.jid, rc.replace,
246 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
250 if (strncasecmp(ua->cmd, ".mod ", 5) == 0 ||
251 (strncasecmp(ua->cmd, "mod ", 4) == 0 && strlen(ua->cmd) > 6)) {
254 if (!scan_command_line_arguments(ua, rc)) {
261 * At user request modify parameters of job to be run.
263 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
266 start_prompt(ua, _("Parameters to modify:\n"));
267 add_prompt(ua, _("Level")); /* 0 */
268 add_prompt(ua, _("Storage")); /* 1 */
269 add_prompt(ua, _("Job")); /* 2 */
270 add_prompt(ua, _("FileSet")); /* 3 */
271 if (jcr->JobType == JT_RESTORE) {
272 add_prompt(ua, _("Restore Client")); /* 4 */
274 add_prompt(ua, _("Client")); /* 4 */
276 add_prompt(ua, _("When")); /* 5 */
277 add_prompt(ua, _("Priority")); /* 6 */
278 if (jcr->JobType == JT_BACKUP ||
279 jcr->JobType == JT_COPY ||
280 jcr->JobType == JT_MIGRATE ||
281 jcr->JobType == JT_VERIFY) {
282 add_prompt(ua, _("Pool")); /* 7 */
283 if (jcr->JobType == JT_VERIFY) {
284 add_prompt(ua, _("Verify Job")); /* 8 */
286 } else if (jcr->JobType == JT_RESTORE) {
287 add_prompt(ua, _("Bootstrap")); /* 7 */
288 add_prompt(ua, _("Where")); /* 8 */
289 add_prompt(ua, _("File Relocation"));/* 9 */
290 add_prompt(ua, _("Replace")); /* 10 */
291 add_prompt(ua, _("JobId")); /* 11 */
293 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
296 select_job_level(ua, jcr);
300 rc.store->store = select_storage_resource(ua);
301 if (rc.store->store) {
302 pm_strcpy(rc.store->store_source, _("user selection"));
303 set_rwstorage(jcr, rc.store);
309 rc.job = select_job_resource(ua);
312 set_jcr_defaults(jcr, rc.job);
318 rc.fileset = select_fileset_resource(ua);
320 jcr->fileset = rc.fileset;
326 rc.client = select_client_resource(ua);
328 jcr->client = rc.client;
334 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
337 if (ua->cmd[0] == 0) {
338 jcr->sched_time = time(NULL);
340 jcr->sched_time = str_to_utime(ua->cmd);
341 if (jcr->sched_time == 0) {
342 ua->send_msg(_("Invalid time, using current time.\n"));
343 jcr->sched_time = time(NULL);
349 if (!get_pint(ua, _("Enter new Priority: "))) {
352 if (ua->pint32_val == 0) {
353 ua->send_msg(_("Priority must be a positive integer.\n"));
355 jcr->JobPriority = ua->pint32_val;
359 /* Pool or Bootstrap depending on JobType */
360 if (jcr->JobType == JT_BACKUP ||
361 jcr->JobType == JT_COPY ||
362 jcr->JobType == JT_MIGRATE ||
363 jcr->JobType == JT_VERIFY) { /* Pool */
364 rc.pool = select_pool_resource(ua);
367 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
374 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
377 if (jcr->RestoreBootstrap) {
378 free(jcr->RestoreBootstrap);
379 jcr->RestoreBootstrap = NULL;
381 if (ua->cmd[0] != 0) {
382 jcr->RestoreBootstrap = bstrdup(ua->cmd);
383 fd = fopen(jcr->RestoreBootstrap, "rb");
386 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
387 jcr->RestoreBootstrap, be.bstrerror());
388 free(jcr->RestoreBootstrap);
389 jcr->RestoreBootstrap = NULL;
397 if (jcr->JobType == JT_VERIFY) {
398 rc.verify_job = select_job_resource(ua);
400 jcr->verify_job = rc.verify_job;
405 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
408 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
409 free(jcr->RegexWhere);
410 jcr->RegexWhere = NULL;
416 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
419 jcr->where = bstrdup(ua->cmd);
422 /* File relocation */
423 select_where_regexp(ua, jcr);
427 start_prompt(ua, _("Replace:\n"));
428 for (i=0; ReplaceOptions[i].name; i++) {
429 add_prompt(ua, ReplaceOptions[i].name);
431 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
433 rc.replace = ReplaceOptions[opt].name;
434 jcr->replace = ReplaceOptions[opt].token;
439 rc.jid = NULL; /* force reprompt */
440 jcr->RestoreJobId = 0;
441 if (jcr->RestoreBootstrap) {
442 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
445 case -1: /* error or cancel */
453 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
455 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
458 Dmsg3(100, "JobId=%u using pool %s priority=%d\n", (int)jcr->JobId,
459 jcr->pool->name(), jcr->JobPriority);
460 JobId = run_job(jcr);
461 Dmsg4(100, "JobId=%u NewJobId=%d using pool %s priority=%d\n", (int)jcr->JobId,
462 JobId, jcr->pool->name(), jcr->JobPriority);
463 free_jcr(jcr); /* release jcr */
465 ua->error_msg(_("Job failed.\n"));
468 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
474 ua->send_msg(_("Job not run.\n"));
476 return 0; /* do not run */
479 static void select_where_regexp(UAContext *ua, JCR *jcr)
482 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
483 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
486 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
487 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
489 start_prompt(ua, _("This will replace your current Where value\n"));
490 add_prompt(ua, _("Strip prefix")); /* 0 */
491 add_prompt(ua, _("Add prefix")); /* 1 */
492 add_prompt(ua, _("Add file suffix")); /* 2 */
493 add_prompt(ua, _("Enter a regexp")); /* 3 */
494 add_prompt(ua, _("Test filename manipulation")); /* 4 */
495 add_prompt(ua, _("Use this ?")); /* 5 */
497 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
500 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
501 if (strip_prefix) bfree(strip_prefix);
502 strip_prefix = bstrdup(ua->cmd);
508 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
509 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
513 if (add_prefix) bfree(add_prefix);
514 add_prefix = bstrdup(ua->cmd);
519 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
520 if (add_suffix) bfree(add_suffix);
521 add_suffix = bstrdup(ua->cmd);
526 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
527 if (rwhere) bfree(rwhere);
528 rwhere = bstrdup(ua->cmd);
537 if (rwhere && rwhere[0] != '\0') {
538 regs = get_bregexps(rwhere);
539 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
541 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
542 regexp = (char *) bmalloc (len * sizeof(char));
543 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
544 regs = get_bregexps(regexp);
545 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
546 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
552 ua->send_msg(_("Cannot use your regexp\n"));
556 while (get_cmd(ua, _("Please enter filename to test: "))) {
557 apply_bregexps(ua->cmd, regs, &result);
558 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
567 case -1: /* error or cancel */
573 /* replace the existing where */
579 /* replace the existing regexwhere */
580 if (jcr->RegexWhere) {
581 bfree(jcr->RegexWhere);
582 jcr->RegexWhere = NULL;
586 jcr->RegexWhere = bstrdup(rwhere);
587 } else if (strip_prefix || add_prefix || add_suffix) {
588 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
589 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
590 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
593 regs = get_bregexps(jcr->RegexWhere);
598 if (jcr->RegexWhere) {
599 bfree(jcr->RegexWhere);
600 jcr->RegexWhere = NULL;
602 ua->send_msg(_("Cannot use your regexp.\n"));
606 if (strip_prefix) bfree(strip_prefix);
607 if (add_prefix) bfree(add_prefix);
608 if (add_suffix) bfree(add_suffix);
609 if (rwhere) bfree(rwhere);
612 static void select_job_level(UAContext *ua, JCR *jcr)
614 if (jcr->JobType == JT_BACKUP) {
615 start_prompt(ua, _("Levels:\n"));
616 add_prompt(ua, _("Base"));
617 add_prompt(ua, _("Full"));
618 add_prompt(ua, _("Incremental"));
619 add_prompt(ua, _("Differential"));
620 add_prompt(ua, _("Since"));
621 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
623 jcr->JobLevel = L_BASE;
626 jcr->JobLevel = L_FULL;
629 jcr->JobLevel = L_INCREMENTAL;
632 jcr->JobLevel = L_DIFFERENTIAL;
635 jcr->JobLevel = L_SINCE;
640 } else if (jcr->JobType == JT_VERIFY) {
641 start_prompt(ua, _("Levels:\n"));
642 add_prompt(ua, _("Initialize Catalog"));
643 add_prompt(ua, _("Verify Catalog"));
644 add_prompt(ua, _("Verify Volume to Catalog"));
645 add_prompt(ua, _("Verify Disk to Catalog"));
646 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
647 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
649 jcr->JobLevel = L_VERIFY_INIT;
652 jcr->JobLevel = L_VERIFY_CATALOG;
655 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
658 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
661 jcr->JobLevel = L_VERIFY_DATA;
667 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
672 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, const char *verify_list,
673 char *jid, const char *replace, char *client_name)
675 Dmsg1(800, "JobType=%c\n", jcr->JobType);
676 switch (jcr->JobType) {
678 char dt[MAX_TIME_LENGTH];
680 if (ua->api) ua->signal(BNET_RUN_CMD);
681 ua->send_msg(_("Run %s job\n"
690 jcr->fileset->name(),
691 NPRT(jcr->client->name()),
692 jcr->wstore?jcr->wstore->name():"*None*",
693 bstrutime(dt, sizeof(dt), jcr->sched_time),
695 jcr->JobLevel = L_FULL;
699 if (jcr->JobType == JT_BACKUP) {
700 if (ua->api) ua->signal(BNET_RUN_CMD);
701 ua->send_msg(_("Run %s job\n"
706 "Pool: %s (From %s)\n"
707 "Storage: %s (From %s)\n"
712 level_to_str(jcr->JobLevel),
714 jcr->fileset->name(),
715 NPRT(jcr->pool->name()), jcr->pool_source,
716 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
717 bstrutime(dt, sizeof(dt), jcr->sched_time),
719 } else { /* JT_VERIFY */
721 if (jcr->verify_job) {
722 Name = jcr->verify_job->name();
727 verify_list = job->WriteVerifyList;
732 if (ua->api) ua->signal(BNET_RUN_CMD);
733 ua->send_msg(_("Run %s job\n"
738 "Pool: %s (From %s)\n"
739 "Storage: %s (From %s)\n"
746 level_to_str(jcr->JobLevel),
748 jcr->fileset->name(),
749 NPRT(jcr->pool->name()), jcr->pool_source,
750 jcr->rstore->name(), jcr->rstore_source,
753 bstrutime(dt, sizeof(dt), jcr->sched_time),
758 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
760 jcr->RestoreJobId = str_to_int64(jid);
762 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
765 jcr->RestoreJobId = ua->int64_val;
768 jcr->JobLevel = L_FULL; /* default level */
769 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
770 if (jcr->RestoreJobId == 0) {
771 if (ua->api) ua->signal(BNET_RUN_CMD);
772 /* RegexWhere is take before RestoreWhere */
773 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
774 ua->send_msg(_("Run Restore job\n"
780 "Backup Client: %s\n"
781 "Restore Client: %s\n"
787 NPRT(jcr->RestoreBootstrap),
788 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
790 jcr->fileset->name(),
794 bstrutime(dt, sizeof(dt), jcr->sched_time),
795 jcr->catalog->name(),
799 ua->send_msg(_("Run Restore job\n"
805 "Backup Client: %s\n"
806 "Restore Client: %s\n"
812 NPRT(jcr->RestoreBootstrap),
813 jcr->where?jcr->where:NPRT(job->RestoreWhere),
815 jcr->fileset->name(),
819 bstrutime(dt, sizeof(dt), jcr->sched_time),
820 jcr->catalog->name(),
825 if (ua->api) ua->signal(BNET_RUN_CMD);
826 ua->send_msg(_("Run Restore job\n"
830 NPRT(jcr->RestoreBootstrap));
832 /* RegexWhere is take before RestoreWhere */
833 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
834 ua->send_msg(_("RegexWhere: %s\n"),
835 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
837 ua->send_msg(_("Where: %s\n"),
838 jcr->where?jcr->where:NPRT(job->RestoreWhere));
841 ua->send_msg(_("Replace: %s\n"
851 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
852 bstrutime(dt, sizeof(dt), jcr->sched_time),
853 jcr->catalog->name(),
860 if (jcr->JobType == JT_COPY) {
861 prt_type = _("Run Copy job\n");
863 prt_type = _("Run Migration job\n");
865 jcr->JobLevel = L_FULL; /* default level */
866 if (ua->api) ua->signal(BNET_RUN_CMD);
872 "Pool: %s (From %s)\n"
873 "Read Storage: %s (From %s)\n"
874 "Write Storage: %s (From %s)\n"
881 NPRT(jcr->RestoreBootstrap),
883 jcr->fileset->name(),
884 NPRT(jcr->pool->name()), jcr->pool_source,
885 jcr->rstore->name(), jcr->rstore_source,
886 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
887 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
888 bstrutime(dt, sizeof(dt), jcr->sched_time),
889 jcr->catalog->name(),
893 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
900 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
904 static const char *kw[] = { /* command line arguments */
905 "job", /* Used in a switch() */
913 "regexwhere", /* 8 where string as a bregexp */
915 "bootstrap", /* 10 */
919 "yes", /* 14 -- if you change this change YES_POS too */
920 "verifyjob", /* 15 */
921 "files", /* 16 number of files to restore */
922 "catalog", /* 17 override catalog */
923 "since", /* 18 since */
924 "cloned", /* 19 cloned */
925 "verifylist", /* 20 verify output list */
926 "migrationjob", /* 21 migration job name */
928 "backupclient", /* 23 */
929 "restoreclient", /* 24 */
934 rc.catalog_name = NULL;
937 rc.store_name = NULL;
938 rc.client_name = NULL;
939 rc.restore_client_name = NULL;
940 rc.fileset_name = NULL;
941 rc.verify_job_name = NULL;
942 rc.previous_job_name = NULL;
945 for (i=1; i<ua->argc; i++) {
946 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
948 /* Keep looking until we find a good keyword */
949 for (j=0; !kw_ok && kw[j]; j++) {
950 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
951 /* Note, yes and run have no value, so do not fail */
952 if (!ua->argv[i] && j != YES_POS /*yes*/) {
953 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
956 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
960 ua->send_msg(_("Job name specified twice.\n"));
963 rc.job_name = ua->argv[i];
967 if (rc.jid && !rc.mod) {
968 ua->send_msg(_("JobId specified twice.\n"));
971 rc.jid = ua->argv[i];
976 if (rc.client_name) {
977 ua->send_msg(_("Client specified twice.\n"));
980 rc.client_name = ua->argv[i];
983 case 4: /* fileset */
984 if (rc.fileset_name) {
985 ua->send_msg(_("FileSet specified twice.\n"));
988 rc.fileset_name = ua->argv[i];
993 ua->send_msg(_("Level specified twice.\n"));
996 rc.level_name = ua->argv[i];
999 case 6: /* storage */
1001 if (rc.store_name) {
1002 ua->send_msg(_("Storage specified twice.\n"));
1005 rc.store_name = ua->argv[i];
1008 case 8: /* regexwhere */
1009 if ((rc.regexwhere || rc.where) && !rc.mod) {
1010 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
1013 rc.regexwhere = ua->argv[i];
1014 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
1015 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
1021 if ((rc.where || rc.regexwhere) && !rc.mod) {
1022 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
1025 rc.where = ua->argv[i];
1026 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
1027 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
1032 case 10: /* bootstrap */
1033 if (rc.bootstrap && !rc.mod) {
1034 ua->send_msg(_("Bootstrap specified twice.\n"));
1037 rc.bootstrap = ua->argv[i];
1040 case 11: /* replace */
1041 if (rc.replace && !rc.mod) {
1042 ua->send_msg(_("Replace specified twice.\n"));
1045 rc.replace = ua->argv[i];
1049 if (rc.when && !rc.mod) {
1050 ua->send_msg(_("When specified twice.\n"));
1053 rc.when = ua->argv[i];
1056 case 13: /* Priority */
1057 if (rc.Priority && !rc.mod) {
1058 ua->send_msg(_("Priority specified twice.\n"));
1061 rc.Priority = atoi(ua->argv[i]);
1062 if (rc.Priority <= 0) {
1063 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1071 case 15: /* Verify Job */
1072 if (rc.verify_job_name) {
1073 ua->send_msg(_("Verify Job specified twice.\n"));
1076 rc.verify_job_name = ua->argv[i];
1079 case 16: /* files */
1080 rc.files = atoi(ua->argv[i]);
1084 case 17: /* catalog */
1085 rc.catalog_name = ua->argv[i];
1089 case 18: /* since */
1090 rc.since = ua->argv[i];
1094 case 19: /* cloned */
1099 case 20: /* write verify list output */
1100 rc.verify_list = ua->argv[i];
1103 case 21: /* Migration Job */
1104 if (rc.previous_job_name) {
1105 ua->send_msg(_("Migration Job specified twice.\n"));
1108 rc.previous_job_name = ua->argv[i];
1113 ua->send_msg(_("Pool specified twice.\n"));
1116 rc.pool_name = ua->argv[i];
1119 case 23: /* backupclient */
1120 if (rc.client_name) {
1121 ua->send_msg(_("Client specified twice.\n"));
1124 rc.client_name = ua->argv[i];
1127 case 24: /* restoreclient */
1128 if (rc.restore_client_name && !rc.mod) {
1129 ua->send_msg(_("Restore Client specified twice.\n"));
1132 rc.restore_client_name = ua->argv[i];
1138 } /* end strcase compare */
1139 } /* end keyword loop */
1141 * End of keyword for loop -- if not found, we got a bogus keyword
1144 Dmsg1(800, "%s not found\n", ua->argk[i]);
1146 * Special case for Job Name, it can be the first
1147 * keyword that has no value.
1149 if (!rc.job_name && !ua->argv[i]) {
1150 rc.job_name = ua->argk[i]; /* use keyword as job name */
1151 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1153 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1157 } /* end argc loop */
1159 Dmsg0(800, "Done scan.\n");
1161 if (rc.catalog_name) {
1162 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1163 if (rc.catalog == NULL) {
1164 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1167 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1168 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1172 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1176 rc.job = GetJobResWithName(rc.job_name);
1178 if (*rc.job_name != 0) {
1179 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1181 rc.job = select_job_resource(ua);
1183 Dmsg1(800, "Found job=%s\n", rc.job_name);
1185 } else if (!rc.job) {
1186 ua->send_msg(_("A job name must be specified.\n"));
1187 rc.job = select_job_resource(ua);
1191 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1192 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1197 rc.pool = GetPoolResWithName(rc.pool_name);
1199 if (*rc.pool_name != 0) {
1200 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1202 rc.pool = select_pool_resource(ua);
1204 } else if (!rc.pool) {
1205 rc.pool = rc.job->pool; /* use default */
1209 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1210 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1213 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1215 if (rc.store_name) {
1216 rc.store->store = GetStoreResWithName(rc.store_name);
1217 pm_strcpy(rc.store->store_source, _("command line"));
1218 if (!rc.store->store) {
1219 if (*rc.store_name != 0) {
1220 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1222 rc.store->store = select_storage_resource(ua);
1223 pm_strcpy(rc.store->store_source, _("user selection"));
1225 } else if (!rc.store->store) {
1226 get_job_storage(rc.store, rc.job, NULL); /* use default */
1228 if (!rc.store->store) {
1229 ua->error_msg(_("No storage specified.\n"));
1231 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1232 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1233 rc.store->store->name());
1236 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1238 if (rc.client_name) {
1239 rc.client = GetClientResWithName(rc.client_name);
1241 if (*rc.client_name != 0) {
1242 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name);
1244 rc.client = select_client_resource(ua);
1246 } else if (!rc.client) {
1247 rc.client = rc.job->client; /* use default */
1251 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1252 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1256 Dmsg1(800, "Using client=%s\n", rc.client->name());
1258 if (rc.restore_client_name) {
1259 rc.client = GetClientResWithName(rc.restore_client_name);
1261 if (*rc.restore_client_name != 0) {
1262 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1264 rc.client = select_client_resource(ua);
1266 } else if (!rc.client) {
1267 rc.client = rc.job->client; /* use default */
1271 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1272 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1276 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1279 if (rc.fileset_name) {
1280 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1282 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1283 rc.fileset = select_fileset_resource(ua);
1285 } else if (!rc.fileset) {
1286 rc.fileset = rc.job->fileset; /* use default */
1290 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1291 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1292 rc.fileset->name());
1296 if (rc.verify_job_name) {
1297 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1298 if (!rc.verify_job) {
1299 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1300 rc.verify_job = select_job_resource(ua);
1302 } else if (!rc.verify_job) {
1303 rc.verify_job = rc.job->verify_job;
1306 if (rc.previous_job_name) {
1307 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1308 if (!rc.previous_job) {
1309 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1310 rc.previous_job = select_job_resource(ua);
1313 rc.previous_job = rc.job->verify_job;