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
40 /* Forward referenced subroutines */
41 static void select_job_level(UAContext *ua, JCR *jcr);
42 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job,
43 char *verify_list, char *jid, const char *replace,
45 static void select_where_regexp(UAContext *ua, JCR *jcr);
48 /* Imported variables */
49 extern struct s_kw ReplaceOptions[];
52 * For Backup and Verify Jobs
53 * run [job=]<job-name> level=<level-name>
62 int run_cmd(UAContext *ua, const char *cmd)
65 char *job_name, *level_name, *jid, *store_name, *pool_name;
66 char *where, *fileset_name, *client_name, *bootstrap, *regexwhere;
67 char *restore_client_name;
69 char *when, *verify_job_name, *catalog_name;
70 char *previous_job_name;
75 int i, j, opt, files = 0;
78 JOB *verify_job = NULL;
79 JOB *previous_job = NULL;
81 CLIENT *client = NULL;
82 FILESET *fileset = NULL;
84 static const char *kw[] = { /* command line arguments */
85 "job", /* Used in a switch() */
93 "regexwhere", /* 8 where string as a bregexp */
99 "yes", /* 14 -- if you change this change YES_POS too */
100 "verifyjob", /* 15 */
101 "files", /* 16 number of files to restore */
102 "catalog", /* 17 override catalog */
103 "since", /* 18 since */
104 "cloned", /* 19 cloned */
105 "verifylist", /* 20 verify output list */
106 "migrationjob", /* 21 migration job name */
108 "backupclient", /* 23 */
109 "restoreclient", /* 24 */
114 if (!open_client_db(ua)) {
127 restore_client_name = NULL;
131 verify_job_name = NULL;
132 previous_job_name = NULL;
136 for (i=1; i<ua->argc; i++) {
137 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
139 /* Keep looking until we find a good keyword */
140 for (j=0; !kw_ok && kw[j]; j++) {
141 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
142 /* Note, yes and run have no value, so do not fail */
143 if (!ua->argv[i] && j != YES_POS /*yes*/) {
144 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
147 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
151 ua->send_msg(_("Job name specified twice.\n"));
154 job_name = ua->argv[i];
159 ua->send_msg(_("JobId specified twice.\n"));
168 ua->send_msg(_("Client specified twice.\n"));
171 client_name = ua->argv[i];
174 case 4: /* fileset */
176 ua->send_msg(_("FileSet specified twice.\n"));
179 fileset_name = ua->argv[i];
184 ua->send_msg(_("Level specified twice.\n"));
187 level_name = ua->argv[i];
190 case 6: /* storage */
193 ua->send_msg(_("Storage specified twice.\n"));
196 store_name = ua->argv[i];
199 case 8: /* regexwhere */
200 if (regexwhere || where) {
201 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
204 regexwhere = ua->argv[i];
205 if (!acl_access_ok(ua, Where_ACL, regexwhere)) {
206 ua->send_msg(_("Forbidden \"regexwhere\" specified.\n"));
212 if (where || regexwhere) {
213 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
217 if (!acl_access_ok(ua, Where_ACL, where)) {
218 ua->send_msg(_("Forbidden \"where\" specified.\n"));
223 case 10: /* bootstrap */
225 ua->send_msg(_("Bootstrap specified twice.\n"));
228 bootstrap = ua->argv[i];
231 case 11: /* replace */
233 ua->send_msg(_("Replace specified twice.\n"));
236 replace = ua->argv[i];
241 ua->send_msg(_("When specified twice.\n"));
247 case 13: /* Priority */
249 ua->send_msg(_("Priority specified twice.\n"));
252 Priority = atoi(ua->argv[i]);
254 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
262 case 15: /* Verify Job */
263 if (verify_job_name) {
264 ua->send_msg(_("Verify Job specified twice.\n"));
267 verify_job_name = ua->argv[i];
271 files = atoi(ua->argv[i]);
275 case 17: /* catalog */
276 catalog_name = ua->argv[i];
285 case 19: /* cloned */
290 case 20: /* write verify list output */
291 verify_list = ua->argv[i];
294 case 21: /* Migration Job */
295 if (previous_job_name) {
296 ua->send_msg(_("Migration Job specified twice.\n"));
299 previous_job_name = ua->argv[i];
304 ua->send_msg(_("Pool specified twice.\n"));
307 pool_name = ua->argv[i];
310 case 23: /* backupclient */
312 ua->send_msg(_("Client specified twice.\n"));
315 client_name = ua->argv[i];
318 case 24: /* restoreclient */
319 if (restore_client_name) {
320 ua->send_msg(_("Restore Client specified twice.\n"));
323 restore_client_name = ua->argv[i];
329 } /* end strcase compare */
330 } /* end keyword loop */
332 * End of keyword for loop -- if not found, we got a bogus keyword
335 Dmsg1(800, "%s not found\n", ua->argk[i]);
337 * Special case for Job Name, it can be the first
338 * keyword that has no value.
340 if (!job_name && !ua->argv[i]) {
341 job_name = ua->argk[i]; /* use keyword as job name */
342 Dmsg1(800, "Set jobname=%s\n", job_name);
344 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
348 } /* end argc loop */
350 Dmsg0(800, "Done scan.\n");
353 if (catalog_name != NULL) {
354 catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name);
355 if (catalog == NULL) {
356 ua->error_msg(_("Catalog \"%s\" not found\n"), catalog_name);
359 if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
360 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), catalog->name());
364 Dmsg1(800, "Using catalog=%s\n", NPRT(catalog_name));
368 job = (JOB *)GetResWithName(R_JOB, job_name);
370 if (*job_name != 0) {
371 ua->send_msg(_("Job \"%s\" not found\n"), job_name);
373 job = select_job_resource(ua);
375 Dmsg1(800, "Found job=%s\n", job_name);
378 ua->send_msg(_("A job name must be specified.\n"));
379 job = select_job_resource(ua);
383 } else if (!acl_access_ok(ua, Job_ACL, job->name())) {
384 ua->error_msg( _("No authorization. Job \"%s\".\n"),
390 pool = (POOL *)GetResWithName(R_POOL, pool_name);
392 if (*pool_name != 0) {
393 ua->warning_msg(_("Pool \"%s\" not found.\n"), pool_name);
395 pool = select_pool_resource(ua);
398 pool = job->pool; /* use default */
402 } else if (!acl_access_ok(ua, Pool_ACL, pool->name())) {
403 ua->error_msg(_("No authorization. Pool \"%s\".\n"),
407 Dmsg1(100, "Using pool %s\n", pool->name());
410 store.store = (STORE *)GetResWithName(R_STORAGE, store_name);
411 pm_strcpy(store.store_source, _("command line"));
413 if (*store_name != 0) {
414 ua->warning_msg(_("Storage \"%s\" not found.\n"), store_name);
416 store.store = select_storage_resource(ua);
417 pm_strcpy(store.store_source, _("user selection"));
420 get_job_storage(&store, job, NULL); /* use default */
423 ua->error_msg(_("No storage specified.\n"));
425 } else if (!acl_access_ok(ua, Storage_ACL, store.store->name())) {
426 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
427 store.store->name());
430 Dmsg1(800, "Using storage=%s\n", store.store->name());
433 client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
435 if (*client_name != 0) {
436 ua->warning_msg(_("Client \"%s\" not found.\n"), client_name);
438 client = select_client_resource(ua);
441 client = job->client; /* use default */
445 } else if (!acl_access_ok(ua, Client_ACL, client->name())) {
446 ua->error_msg(_("No authorization. Client \"%s\".\n"),
450 Dmsg1(800, "Using client=%s\n", client->name());
452 if (restore_client_name) {
453 client = (CLIENT *)GetResWithName(R_CLIENT, restore_client_name);
455 if (*restore_client_name != 0) {
456 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), restore_client_name);
458 client = select_client_resource(ua);
461 client = job->client; /* use default */
465 } else if (!acl_access_ok(ua, Client_ACL, client->name())) {
466 ua->error_msg(_("No authorization. Client \"%s\".\n"),
470 Dmsg1(800, "Using restore client=%s\n", client->name());
474 fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
476 ua->send_msg(_("FileSet \"%s\" not found.\n"), fileset_name);
477 fileset = select_fileset_resource(ua);
480 fileset = job->fileset; /* use default */
484 } else if (!acl_access_ok(ua, FileSet_ACL, fileset->name())) {
485 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
490 if (verify_job_name) {
491 verify_job = (JOB *)GetResWithName(R_JOB, verify_job_name);
493 ua->send_msg(_("Verify Job \"%s\" not found.\n"), verify_job_name);
494 verify_job = select_job_resource(ua);
497 verify_job = job->verify_job;
500 if (previous_job_name) {
501 previous_job = (JOB *)GetResWithName(R_JOB, previous_job_name);
503 ua->send_msg(_("Migration Job \"%s\" not found.\n"), previous_job_name);
504 previous_job = select_job_resource(ua);
507 previous_job = job->verify_job;
512 * Create JCR to run job. NOTE!!! after this point, free_jcr()
515 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
516 set_jcr_defaults(jcr, job);
517 jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */
518 ua->jcr->unlink_bsr = false;
520 jcr->verify_job = verify_job;
521 jcr->previous_job = previous_job;
523 set_rwstorage(jcr, &store);
524 jcr->client = client;
525 pm_strcpy(jcr->client_name, client->name());
526 jcr->fileset = fileset;
527 jcr->ExpectedFiles = files;
528 if (catalog != NULL) {
529 jcr->catalog = catalog;
535 jcr->where = bstrdup(where);
539 if (jcr->RegexWhere) {
540 free(jcr->RegexWhere);
542 jcr->RegexWhere = bstrdup(regexwhere);
546 jcr->sched_time = str_to_utime(when);
547 if (jcr->sched_time == 0) {
548 ua->send_msg(_("Invalid time, using current time.\n"));
549 jcr->sched_time = time(NULL);
554 if (jcr->RestoreBootstrap) {
555 free(jcr->RestoreBootstrap);
557 jcr->RestoreBootstrap = bstrdup(bootstrap);
562 for (i=0; ReplaceOptions[i].name; i++) {
563 if (strcasecmp(replace, ReplaceOptions[i].name) == 0) {
564 jcr->replace = ReplaceOptions[i].token;
568 ua->send_msg(_("Invalid replace option: %s\n"), replace);
571 } else if (job->replace) {
572 jcr->replace = job->replace;
574 jcr->replace = REPLACE_ALWAYS;
578 jcr->JobPriority = Priority;
583 jcr->stime = get_pool_memory(PM_MESSAGE);
585 pm_strcpy(jcr->stime, since);
588 jcr->cloned = cloned;
590 if (find_arg(ua, NT_("fdcalled")) > 0) {
591 jcr->file_bsock = dup_bsock(ua->UA_sock);
596 /* If pool changed, update migration write storage */
597 if (jcr->JobType == JT_MIGRATE) {
598 if (!set_migration_wstorage(jcr, pool)) {
602 replace = ReplaceOptions[0].name;
603 for (i=0; ReplaceOptions[i].name; i++) {
604 if (ReplaceOptions[i].token == jcr->replace) {
605 replace = ReplaceOptions[i].name;
609 if (!get_level_from_name(jcr, level_name)) {
610 ua->send_msg(_("Level %s not valid.\n"), level_name);
615 /* Note, this is also MigrateJobId */
616 jcr->RestoreJobId = str_to_int64(jid);
619 /* Run without prompting? */
620 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
625 * Prompt User to see if all run job parameters are correct, and
626 * allow him to modify them.
628 if (!display_job_parameters(ua, jcr, job, verify_list, jid, replace,
633 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
638 * At user request modify parameters of job to be run.
640 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
643 start_prompt(ua, _("Parameters to modify:\n"));
644 add_prompt(ua, _("Level")); /* 0 */
645 add_prompt(ua, _("Storage")); /* 1 */
646 add_prompt(ua, _("Job")); /* 2 */
647 add_prompt(ua, _("FileSet")); /* 3 */
648 if (jcr->JobType == JT_RESTORE) {
649 add_prompt(ua, _("Restore Client")); /* 4 */
651 add_prompt(ua, _("Client")); /* 4 */
653 add_prompt(ua, _("When")); /* 5 */
654 add_prompt(ua, _("Priority")); /* 6 */
655 if (jcr->JobType == JT_BACKUP ||
656 jcr->JobType == JT_MIGRATE ||
657 jcr->JobType == JT_VERIFY) {
658 add_prompt(ua, _("Pool")); /* 7 */
659 if (jcr->JobType == JT_VERIFY) {
660 add_prompt(ua, _("Verify Job")); /* 8 */
662 } else if (jcr->JobType == JT_RESTORE) {
663 add_prompt(ua, _("Bootstrap")); /* 7 */
664 add_prompt(ua, _("Where")); /* 8 */
665 add_prompt(ua, _("File Relocation"));/* 9 */
666 add_prompt(ua, _("Replace")); /* 10 */
667 add_prompt(ua, _("JobId")); /* 11 */
669 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
672 select_job_level(ua, jcr);
676 store.store = select_storage_resource(ua);
678 pm_strcpy(store.store_source, _("user selection"));
679 set_rwstorage(jcr, &store);
685 job = select_job_resource(ua);
688 set_jcr_defaults(jcr, job);
694 fileset = select_fileset_resource(ua);
696 jcr->fileset = fileset;
702 client = select_client_resource(ua);
704 jcr->client = client;
710 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
713 if (ua->cmd[0] == 0) {
714 jcr->sched_time = time(NULL);
716 jcr->sched_time = str_to_utime(ua->cmd);
717 if (jcr->sched_time == 0) {
718 ua->send_msg(_("Invalid time, using current time.\n"));
719 jcr->sched_time = time(NULL);
725 if (!get_pint(ua, _("Enter new Priority: "))) {
728 if (ua->pint32_val == 0) {
729 ua->send_msg(_("Priority must be a positive integer.\n"));
731 jcr->JobPriority = ua->pint32_val;
735 /* Pool or Bootstrap depending on JobType */
736 if (jcr->JobType == JT_BACKUP ||
737 jcr->JobType == JT_MIGRATE ||
738 jcr->JobType == JT_VERIFY) { /* Pool */
739 pool = select_pool_resource(ua);
742 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
749 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
752 if (jcr->RestoreBootstrap) {
753 free(jcr->RestoreBootstrap);
754 jcr->RestoreBootstrap = NULL;
756 if (ua->cmd[0] != 0) {
757 jcr->RestoreBootstrap = bstrdup(ua->cmd);
758 fd = fopen(jcr->RestoreBootstrap, "rb");
760 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
761 jcr->RestoreBootstrap, strerror(errno));
762 free(jcr->RestoreBootstrap);
763 jcr->RestoreBootstrap = NULL;
771 if (jcr->JobType == JT_VERIFY) {
772 verify_job = select_job_resource(ua);
774 jcr->verify_job = verify_job;
779 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
782 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
783 free(jcr->RegexWhere);
784 jcr->RegexWhere = NULL;
790 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
793 jcr->where = bstrdup(ua->cmd);
796 /* File relocation */
797 select_where_regexp(ua, jcr);
801 start_prompt(ua, _("Replace:\n"));
802 for (i=0; ReplaceOptions[i].name; i++) {
803 add_prompt(ua, ReplaceOptions[i].name);
805 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
807 jcr->replace = ReplaceOptions[opt].token;
812 jid = NULL; /* force reprompt */
813 jcr->RestoreJobId = 0;
814 if (jcr->RestoreBootstrap) {
815 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
818 case -1: /* error or cancel */
826 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
828 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
830 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
831 JobId = run_job(jcr);
833 ua->send_msg("<job director=\"console\" time=\"%u\" status=\"%c\" type=\"%c\" "
834 "jobid=\"%u\" job=\"%s\" level=\"%c\" finished=\"false\" priority=\"%u\"/>\n",
835 time(NULL), jcr->JobStatus, jcr->JobType, jcr->JobId,
836 jcr->Job, jcr->JobLevel, jcr->JobPriority);
838 free_jcr(jcr); /* release jcr */
840 ua->error_msg(_("Job failed.\n"));
843 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId,ed1));
849 ua->send_msg(_("Job not run.\n"));
851 return 0; /* do not run */
854 static void select_where_regexp(UAContext *ua, JCR *jcr)
857 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
858 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
861 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
862 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
864 start_prompt(ua, _("This will replace your current Where value\n"));
865 add_prompt(ua, _("Strip prefix")); /* 0 */
866 add_prompt(ua, _("Add prefix")); /* 1 */
867 add_prompt(ua, _("Add file suffix")); /* 2 */
868 add_prompt(ua, _("Enter a regexp")); /* 3 */
869 add_prompt(ua, _("Test filename manipulation")); /* 4 */
870 add_prompt(ua, _("Use this ?")); /* 5 */
872 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
875 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
876 if (strip_prefix) bfree(strip_prefix);
877 strip_prefix = bstrdup(ua->cmd);
883 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
884 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
888 if (add_prefix) bfree(add_prefix);
889 add_prefix = bstrdup(ua->cmd);
894 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
895 if (add_suffix) bfree(add_suffix);
896 add_suffix = bstrdup(ua->cmd);
901 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
902 if (rwhere) bfree(rwhere);
903 rwhere = bstrdup(ua->cmd);
912 if (rwhere && rwhere[0] != '\0') {
913 regs = get_bregexps(rwhere);
914 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
916 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
917 regexp = (char *) bmalloc (len * sizeof(char));
918 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
919 regs = get_bregexps(regexp);
920 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
921 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
927 ua->send_msg(_("Cannot use your regexp\n"));
931 while (get_cmd(ua, _("Please enter filename to test: "))) {
932 apply_bregexps(ua->cmd, regs, &result);
933 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
942 case -1: /* error or cancel */
948 /* replace the existing where */
954 /* replace the existing regexwhere */
955 if (jcr->RegexWhere) {
956 bfree(jcr->RegexWhere);
957 jcr->RegexWhere = NULL;
961 jcr->RegexWhere = bstrdup(rwhere);
962 } else if (strip_prefix || add_prefix || add_suffix) {
963 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
964 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
965 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
968 regs = get_bregexps(jcr->RegexWhere);
973 if (jcr->RegexWhere) {
974 bfree(jcr->RegexWhere);
975 jcr->RegexWhere = NULL;
977 ua->send_msg(_("Cannot use your regexp.\n"));
981 if (strip_prefix) bfree(strip_prefix);
982 if (add_prefix) bfree(add_prefix);
983 if (add_suffix) bfree(add_suffix);
984 if (rwhere) bfree(rwhere);
987 static void select_job_level(UAContext *ua, JCR *jcr)
989 if (jcr->JobType == JT_BACKUP) {
990 start_prompt(ua, _("Levels:\n"));
991 add_prompt(ua, _("Base"));
992 add_prompt(ua, _("Full"));
993 add_prompt(ua, _("Incremental"));
994 add_prompt(ua, _("Differential"));
995 add_prompt(ua, _("Since"));
996 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
998 jcr->JobLevel = L_BASE;
1001 jcr->JobLevel = L_FULL;
1004 jcr->JobLevel = L_INCREMENTAL;
1007 jcr->JobLevel = L_DIFFERENTIAL;
1010 jcr->JobLevel = L_SINCE;
1015 } else if (jcr->JobType == JT_VERIFY) {
1016 start_prompt(ua, _("Levels:\n"));
1017 add_prompt(ua, _("Initialize Catalog"));
1018 add_prompt(ua, _("Verify Catalog"));
1019 add_prompt(ua, _("Verify Volume to Catalog"));
1020 add_prompt(ua, _("Verify Disk to Catalog"));
1021 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
1022 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
1024 jcr->JobLevel = L_VERIFY_INIT;
1027 jcr->JobLevel = L_VERIFY_CATALOG;
1030 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
1033 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
1036 jcr->JobLevel = L_VERIFY_DATA;
1042 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
1047 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
1048 char *jid, const char *replace, char *client_name)
1050 Dmsg1(800, "JobType=%c\n", jcr->JobType);
1051 switch (jcr->JobType) {
1053 char dt[MAX_TIME_LENGTH];
1055 if (ua->api) ua->signal(BNET_RUN_CMD);
1056 ua->send_msg(_("Run %s job\n"
1065 jcr->fileset->name(),
1066 NPRT(jcr->client->name()),
1067 jcr->wstore?jcr->wstore->name():"*None*",
1068 bstrutime(dt, sizeof(dt), jcr->sched_time),
1070 jcr->JobLevel = L_FULL;
1074 if (jcr->JobType == JT_BACKUP) {
1075 if (ua->api) ua->signal(BNET_RUN_CMD);
1076 ua->send_msg(_("Run %s job\n"
1081 "Pool: %s (From %s)\n"
1082 "Storage: %s (From %s)\n"
1087 level_to_str(jcr->JobLevel),
1088 jcr->client->name(),
1089 jcr->fileset->name(),
1090 NPRT(jcr->pool->name()), jcr->pool_source,
1091 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
1092 bstrutime(dt, sizeof(dt), jcr->sched_time),
1094 } else { /* JT_VERIFY */
1096 if (jcr->verify_job) {
1097 Name = jcr->verify_job->name();
1102 verify_list = job->WriteVerifyList;
1107 if (ua->api) ua->signal(BNET_RUN_CMD);
1108 ua->send_msg(_("Run %s job\n"
1113 "Pool: %s (From %s)\n"
1114 "Storage: %s (From %s)\n"
1121 level_to_str(jcr->JobLevel),
1122 jcr->client->name(),
1123 jcr->fileset->name(),
1124 NPRT(jcr->pool->name()), jcr->pool_source,
1125 jcr->rstore->name(), jcr->rstore_source,
1128 bstrutime(dt, sizeof(dt), jcr->sched_time),
1133 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
1135 jcr->RestoreJobId = str_to_int64(jid);
1137 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
1140 jcr->RestoreJobId = ua->int64_val;
1143 jcr->JobLevel = L_FULL; /* default level */
1144 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
1145 if (jcr->RestoreJobId == 0) {
1146 if (ua->api) ua->signal(BNET_RUN_CMD);
1147 ua->send_msg(_("Run Restore job\n"
1151 NPRT(jcr->RestoreBootstrap));
1153 /* RegexWhere is take before RestoreWhere */
1154 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
1155 ua->send_msg(_("RegexWhere: %s\n"),
1156 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
1158 ua->send_msg(_("Where: %s\n"),
1159 jcr->where?jcr->where:NPRT(job->RestoreWhere));
1162 ua->send_msg(_("Replace: %s\n"
1164 "Backup Client: %s\n"
1165 "Restore Client: %s\n"
1171 jcr->fileset->name(),
1173 jcr->client->name(),
1174 jcr->rstore->name(),
1175 bstrutime(dt, sizeof(dt), jcr->sched_time),
1176 jcr->catalog->name(),
1179 if (ua->api) ua->signal(BNET_RUN_CMD);
1180 ua->send_msg(_("Run Restore job\n"
1184 NPRT(jcr->RestoreBootstrap));
1186 /* RegexWhere is take before RestoreWhere */
1187 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
1188 ua->send_msg(_("RegexWhere: %s\n"),
1189 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
1191 ua->send_msg(_("Where: %s\n"),
1192 jcr->where?jcr->where:NPRT(job->RestoreWhere));
1195 ua->send_msg(_("Replace: %s\n"
1203 jcr->client->name(),
1204 jcr->rstore->name(),
1205 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
1206 bstrutime(dt, sizeof(dt), jcr->sched_time),
1207 jcr->catalog->name(),
1212 jcr->JobLevel = L_FULL; /* default level */
1213 if (ua->api) ua->signal(BNET_RUN_CMD);
1214 ua->send_msg(_("Run Migration job\n"
1219 "Pool: %s (From %s)\n"
1220 "Read Storage: %s (From %s)\n"
1221 "Write Storage: %s (From %s)\n"
1227 NPRT(jcr->RestoreBootstrap),
1228 jcr->client->name(),
1229 jcr->fileset->name(),
1230 NPRT(jcr->pool->name()), jcr->pool_source,
1231 jcr->rstore->name(), jcr->rstore_source,
1232 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
1233 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
1234 bstrutime(dt, sizeof(dt), jcr->sched_time),
1235 jcr->catalog->name(),
1239 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);