3 * Bacula Director -- Run Command
5 * Kern Sibbald, December MMI
10 Bacula® - The Network Backup Solution
12 Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
14 The main author of Bacula is Kern Sibbald, with contributions from
15 many others, a complete list can be found in the file AUTHORS.
16 This program is Free Software; you can redistribute it and/or
17 modify it under the terms of version two of the GNU General Public
18 License as published by the Free Software Foundation plus additions
19 that are listed in the file LICENSE.
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
31 Bacula® is a registered trademark of John Walker.
32 The licensor of Bacula is the Free Software Foundation Europe
33 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
34 Switzerland, email:ftf@fsfeurope.org.
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, char *verify_list,
43 char *jid, const char *replace);
44 static void select_where_regexp(UAContext *ua, JCR *jcr);
47 /* Imported variables */
48 extern struct s_kw ReplaceOptions[];
51 * For Backup and Verify Jobs
52 * run [job=]<job-name> level=<level-name>
61 int run_cmd(UAContext *ua, const char *cmd)
64 char *job_name, *level_name, *jid, *store_name, *pool_name;
65 char *where, *fileset_name, *client_name, *bootstrap;
67 char *when, *verify_job_name, *catalog_name;
68 char *previous_job_name;
73 int i, j, opt, files = 0;
75 bool where_use_regexp = false;
77 JOB *verify_job = NULL;
78 JOB *previous_job = NULL;
80 CLIENT *client = NULL;
81 FILESET *fileset = NULL;
83 static const char *kw[] = { /* command line arguments */
84 "job", /* Used in a switch() */
92 "regexwhere", /* 8 where string as a bregexp */
98 "yes", /* 14 -- if you change this change YES_POS too */
100 "files", /* 16 number of files to restore */
101 "catalog", /* 17 override catalog */
102 "since", /* 18 since */
103 "cloned", /* 19 cloned */
104 "verifylist", /* 20 verify output list */
105 "migrationjob", /* 21 migration job name */
111 if (!open_client_db(ua)) {
126 verify_job_name = NULL;
127 previous_job_name = NULL;
131 for (i=1; i<ua->argc; i++) {
132 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
134 /* Keep looking until we find a good keyword */
135 for (j=0; !kw_ok && kw[j]; j++) {
136 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
137 /* Note, yes and run have no value, so do not fail */
138 if (!ua->argv[i] && j != YES_POS /*yes*/) {
139 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
142 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
146 ua->send_msg(_("Job name specified twice.\n"));
149 job_name = ua->argv[i];
154 ua->send_msg(_("JobId specified twice.\n"));
163 ua->send_msg(_("Client specified twice.\n"));
166 client_name = ua->argv[i];
169 case 4: /* fileset */
171 ua->send_msg(_("FileSet specified twice.\n"));
174 fileset_name = ua->argv[i];
179 ua->send_msg(_("Level specified twice.\n"));
182 level_name = ua->argv[i];
185 case 6: /* storage */
188 ua->send_msg(_("Storage specified twice.\n"));
191 store_name = ua->argv[i];
194 case 8: /* regexwhere */
196 /* TODO: this is ugly ... */
197 where_use_regexp = (j == 9)?false:true;/*regexwhere or where ?*/
200 ua->send_msg(_("Where specified twice.\n"));
204 if (!acl_access_ok(ua, Where_ACL, where)) {
205 ua->send_msg(_("Forbidden \"where\" specified.\n"));
210 case 10: /* bootstrap */
212 ua->send_msg(_("Bootstrap specified twice.\n"));
215 bootstrap = ua->argv[i];
218 case 11: /* replace */
220 ua->send_msg(_("Replace specified twice.\n"));
223 replace = ua->argv[i];
228 ua->send_msg(_("When specified twice.\n"));
234 case 13: /* Priority */
236 ua->send_msg(_("Priority specified twice.\n"));
239 Priority = atoi(ua->argv[i]);
241 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
249 case 15: /* Verify Job */
250 if (verify_job_name) {
251 ua->send_msg(_("Verify Job specified twice.\n"));
254 verify_job_name = ua->argv[i];
258 files = atoi(ua->argv[i]);
262 case 17: /* catalog */
263 catalog_name = ua->argv[i];
272 case 19: /* cloned */
277 case 20: /* write verify list output */
278 verify_list = ua->argv[i];
281 case 21: /* Migration Job */
282 if (previous_job_name) {
283 ua->send_msg(_("Migration Job specified twice.\n"));
286 previous_job_name = ua->argv[i];
291 ua->send_msg(_("Pool specified twice.\n"));
294 pool_name = ua->argv[i];
301 } /* end strcase compare */
302 } /* end keyword loop */
304 * End of keyword for loop -- if not found, we got a bogus keyword
307 Dmsg1(800, "%s not found\n", ua->argk[i]);
309 * Special case for Job Name, it can be the first
310 * keyword that has no value.
312 if (!job_name && !ua->argv[i]) {
313 job_name = ua->argk[i]; /* use keyword as job name */
314 Dmsg1(800, "Set jobname=%s\n", job_name);
316 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
320 } /* end argc loop */
322 Dmsg0(800, "Done scan.\n");
325 if (catalog_name != NULL) {
326 catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name);
327 if (catalog == NULL) {
328 ua->error_msg(_("Catalog \"%s\" not found\n"), catalog_name);
331 if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
332 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), catalog->name());
336 Dmsg1(800, "Using catalog=%s\n", NPRT(catalog_name));
340 job = (JOB *)GetResWithName(R_JOB, job_name);
342 if (*job_name != 0) {
343 ua->send_msg(_("Job \"%s\" not found\n"), job_name);
345 job = select_job_resource(ua);
347 Dmsg1(800, "Found job=%s\n", job_name);
350 ua->send_msg(_("A job name must be specified.\n"));
351 job = select_job_resource(ua);
355 } else if (!acl_access_ok(ua, Job_ACL, job->name())) {
356 ua->error_msg( _("No authorization. Job \"%s\".\n"),
362 pool = (POOL *)GetResWithName(R_POOL, pool_name);
364 if (*pool_name != 0) {
365 ua->warning_msg(_("Pool \"%s\" not found.\n"), pool_name);
367 pool = select_pool_resource(ua);
370 pool = job->pool; /* use default */
374 } else if (!acl_access_ok(ua, Pool_ACL, pool->name())) {
375 ua->error_msg(_("No authorization. Pool \"%s\".\n"),
379 Dmsg1(100, "Using pool %s\n", pool->name());
382 store.store = (STORE *)GetResWithName(R_STORAGE, store_name);
383 pm_strcpy(store.store_source, _("command line"));
385 if (*store_name != 0) {
386 ua->warning_msg(_("Storage \"%s\" not found.\n"), store_name);
388 store.store = select_storage_resource(ua);
389 pm_strcpy(store.store_source, _("user selection"));
392 get_job_storage(&store, job, NULL); /* use default */
395 ua->error_msg(_("No storage specified.\n"));
397 } else if (!acl_access_ok(ua, Storage_ACL, store.store->name())) {
398 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
399 store.store->name());
402 Dmsg1(800, "Using storage=%s\n", store.store->name());
405 client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
407 if (*client_name != 0) {
408 ua->warning_msg(_("Client \"%s\" not found.\n"), client_name);
410 client = select_client_resource(ua);
413 client = job->client; /* use default */
417 } else if (!acl_access_ok(ua, Client_ACL, client->name())) {
418 ua->error_msg(_("No authorization. Client \"%s\".\n"),
422 Dmsg1(800, "Using client=%s\n", client->name());
425 fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
427 ua->send_msg(_("FileSet \"%s\" not found.\n"), fileset_name);
428 fileset = select_fileset_resource(ua);
431 fileset = job->fileset; /* use default */
435 } else if (!acl_access_ok(ua, FileSet_ACL, fileset->name())) {
436 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
441 if (verify_job_name) {
442 verify_job = (JOB *)GetResWithName(R_JOB, verify_job_name);
444 ua->send_msg(_("Verify Job \"%s\" not found.\n"), verify_job_name);
445 verify_job = select_job_resource(ua);
448 verify_job = job->verify_job;
451 if (previous_job_name) {
452 previous_job = (JOB *)GetResWithName(R_JOB, previous_job_name);
454 ua->send_msg(_("Migration Job \"%s\" not found.\n"), previous_job_name);
455 previous_job = select_job_resource(ua);
458 previous_job = job->verify_job;
463 * Create JCR to run job. NOTE!!! after this point, free_jcr()
466 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
467 set_jcr_defaults(jcr, job);
468 jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */
469 ua->jcr->unlink_bsr = false;
471 jcr->verify_job = verify_job;
472 jcr->previous_job = previous_job;
474 set_rwstorage(jcr, &store);
475 jcr->client = client;
476 pm_strcpy(jcr->client_name, client->name());
477 jcr->fileset = fileset;
478 jcr->ExpectedFiles = files;
479 if (catalog != NULL) {
480 jcr->catalog = catalog;
486 jcr->where = bstrdup(where);
487 jcr->where_use_regexp = where_use_regexp;
491 jcr->sched_time = str_to_utime(when);
492 if (jcr->sched_time == 0) {
493 ua->send_msg(_("Invalid time, using current time.\n"));
494 jcr->sched_time = time(NULL);
499 if (jcr->RestoreBootstrap) {
500 free(jcr->RestoreBootstrap);
502 jcr->RestoreBootstrap = bstrdup(bootstrap);
507 for (i=0; ReplaceOptions[i].name; i++) {
508 if (strcasecmp(replace, ReplaceOptions[i].name) == 0) {
509 jcr->replace = ReplaceOptions[i].token;
513 ua->send_msg(_("Invalid replace option: %s\n"), replace);
516 } else if (job->replace) {
517 jcr->replace = job->replace;
519 jcr->replace = REPLACE_ALWAYS;
523 jcr->JobPriority = Priority;
528 jcr->stime = get_pool_memory(PM_MESSAGE);
530 pm_strcpy(jcr->stime, since);
533 jcr->cloned = cloned;
535 if (find_arg(ua, NT_("fdcalled")) > 0) {
536 jcr->file_bsock = dup_bsock(ua->UA_sock);
541 /* If pool changed, update migration write storage */
542 if (jcr->JobType == JT_MIGRATE) {
543 if (!set_migration_wstorage(jcr, pool)) {
547 replace = ReplaceOptions[0].name;
548 for (i=0; ReplaceOptions[i].name; i++) {
549 if (ReplaceOptions[i].token == jcr->replace) {
550 replace = ReplaceOptions[i].name;
554 if (!get_level_from_name(jcr, level_name)) {
555 ua->send_msg(_("Level %s not valid.\n"), level_name);
560 /* Note, this is also MigrateJobId */
561 jcr->RestoreJobId = str_to_int64(jid);
564 /* Run without prompting? */
565 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
570 * Prompt User to see if all run job parameters are correct, and
571 * allow him to modify them.
573 if (!display_job_parameters(ua, jcr, job, verify_list, jid, replace)) {
577 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
582 * At user request modify parameters of job to be run.
584 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
587 start_prompt(ua, _("Parameters to modify:\n"));
588 add_prompt(ua, _("Level")); /* 0 */
589 add_prompt(ua, _("Storage")); /* 1 */
590 add_prompt(ua, _("Job")); /* 2 */
591 add_prompt(ua, _("FileSet")); /* 3 */
592 add_prompt(ua, _("Client")); /* 4 */
593 add_prompt(ua, _("When")); /* 5 */
594 add_prompt(ua, _("Priority")); /* 6 */
595 if (jcr->JobType == JT_BACKUP ||
596 jcr->JobType == JT_MIGRATE ||
597 jcr->JobType == JT_VERIFY) {
598 add_prompt(ua, _("Pool")); /* 7 */
599 if (jcr->JobType == JT_VERIFY) {
600 add_prompt(ua, _("Verify Job")); /* 8 */
602 } else if (jcr->JobType == JT_RESTORE) {
603 add_prompt(ua, _("Bootstrap")); /* 7 */
604 add_prompt(ua, _("Where")); /* 8 */
605 add_prompt(ua, _("File Relocation"));/* 9 */
606 add_prompt(ua, _("Replace")); /* 10 */
607 add_prompt(ua, _("JobId")); /* 11 */
609 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
612 select_job_level(ua, jcr);
616 store.store = select_storage_resource(ua);
618 pm_strcpy(store.store_source, _("user selection"));
619 set_rwstorage(jcr, &store);
625 job = select_job_resource(ua);
628 set_jcr_defaults(jcr, job);
634 fileset = select_fileset_resource(ua);
636 jcr->fileset = fileset;
642 client = select_client_resource(ua);
644 jcr->client = client;
650 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
653 if (ua->cmd[0] == 0) {
654 jcr->sched_time = time(NULL);
656 jcr->sched_time = str_to_utime(ua->cmd);
657 if (jcr->sched_time == 0) {
658 ua->send_msg(_("Invalid time, using current time.\n"));
659 jcr->sched_time = time(NULL);
665 if (!get_pint(ua, _("Enter new Priority: "))) {
668 if (ua->pint32_val == 0) {
669 ua->send_msg(_("Priority must be a positive integer.\n"));
671 jcr->JobPriority = ua->pint32_val;
675 /* Pool or Bootstrap depending on JobType */
676 if (jcr->JobType == JT_BACKUP ||
677 jcr->JobType == JT_MIGRATE ||
678 jcr->JobType == JT_VERIFY) { /* Pool */
679 pool = select_pool_resource(ua);
682 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
689 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
692 if (jcr->RestoreBootstrap) {
693 free(jcr->RestoreBootstrap);
694 jcr->RestoreBootstrap = NULL;
696 if (ua->cmd[0] != 0) {
697 jcr->RestoreBootstrap = bstrdup(ua->cmd);
698 fd = fopen(jcr->RestoreBootstrap, "rb");
700 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
701 jcr->RestoreBootstrap, strerror(errno));
702 free(jcr->RestoreBootstrap);
703 jcr->RestoreBootstrap = NULL;
711 if (jcr->JobType == JT_VERIFY) {
712 verify_job = select_job_resource(ua);
714 jcr->verify_job = verify_job;
719 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
726 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
729 jcr->where = bstrdup(ua->cmd);
730 jcr->where_use_regexp = false;
733 /* File relocation */
734 select_where_regexp(ua, jcr);
738 start_prompt(ua, _("Replace:\n"));
739 for (i=0; ReplaceOptions[i].name; i++) {
740 add_prompt(ua, ReplaceOptions[i].name);
742 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
744 jcr->replace = ReplaceOptions[opt].token;
749 jid = NULL; /* force reprompt */
750 jcr->RestoreJobId = 0;
751 if (jcr->RestoreBootstrap) {
752 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
755 case -1: /* error or cancel */
763 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
765 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
767 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
768 JobId = run_job(jcr);
770 ua->send_msg("<job director=\"console\" time=\"%u\" status=\"%c\" type=\"%c\" "
771 "jobid=\"%u\" job=\"%s\" level=\"%c\" finished=\"false\" priority=\"%u\"/>\n",
772 time(NULL), jcr->JobStatus, jcr->JobType, jcr->JobId,
773 jcr->Job, jcr->JobLevel, jcr->JobPriority);
775 free_jcr(jcr); /* release jcr */
777 ua->error_msg(_("Job failed.\n"));
780 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId,ed1));
786 ua->send_msg(_("Job not run.\n"));
788 return 0; /* do not run */
791 static void select_where_regexp(UAContext *ua, JCR *jcr)
794 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
795 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
798 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
799 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
801 start_prompt(ua, _("This will replace your current Where value\n"));
802 add_prompt(ua, _("Strip prefix")); /* 0 */
803 add_prompt(ua, _("Add prefix")); /* 1 */
804 add_prompt(ua, _("Add file suffix")); /* 2 */
805 add_prompt(ua, _("Enter a regexp")); /* 3 */
806 add_prompt(ua, _("Test filename manipulation")); /* 4 */
807 add_prompt(ua, _("Use this ?")); /* 5 */
809 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
812 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
813 if (strip_prefix) bfree(strip_prefix);
814 strip_prefix = bstrdup(ua->cmd);
820 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
821 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
825 if (add_prefix) bfree(add_prefix);
826 add_prefix = bstrdup(ua->cmd);
831 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
832 if (add_suffix) bfree(add_suffix);
833 add_suffix = bstrdup(ua->cmd);
838 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
839 if (rwhere) bfree(rwhere);
840 rwhere = bstrdup(ua->cmd);
849 if (rwhere && rwhere[0] != '\0') {
850 regs = get_bregexps(rwhere);
851 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
853 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
854 regexp = (char *) bmalloc (len * sizeof(char));
855 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
856 regs = get_bregexps(regexp);
857 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
858 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
864 ua->send_msg(_("Cannot use your regexp\n"));
868 while (get_cmd(ua, _("Please enter filename to test: "))) {
869 apply_bregexps(ua->cmd, regs, &result);
870 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
879 case -1: /* error or cancel */
885 /* replace the existing where */
892 jcr->where = bstrdup(rwhere);
893 } else if (strip_prefix || add_prefix || add_suffix) {
894 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
895 jcr->where = (char *) bmalloc(len*sizeof(char));
896 bregexp_build_where(jcr->where, len, strip_prefix, add_prefix, add_suffix);
899 regs = get_bregexps(jcr->where);
903 jcr->where_use_regexp = true;
909 ua->send_msg(_("Cannot use your regexp.\n"));
913 if (strip_prefix) bfree(strip_prefix);
914 if (add_prefix) bfree(add_prefix);
915 if (add_suffix) bfree(add_suffix);
916 if (rwhere) bfree(rwhere);
919 static void select_job_level(UAContext *ua, JCR *jcr)
921 if (jcr->JobType == JT_BACKUP) {
922 start_prompt(ua, _("Levels:\n"));
923 add_prompt(ua, _("Base"));
924 add_prompt(ua, _("Full"));
925 add_prompt(ua, _("Incremental"));
926 add_prompt(ua, _("Differential"));
927 add_prompt(ua, _("Since"));
928 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
930 jcr->JobLevel = L_BASE;
933 jcr->JobLevel = L_FULL;
936 jcr->JobLevel = L_INCREMENTAL;
939 jcr->JobLevel = L_DIFFERENTIAL;
942 jcr->JobLevel = L_SINCE;
947 } else if (jcr->JobType == JT_VERIFY) {
948 start_prompt(ua, _("Levels:\n"));
949 add_prompt(ua, _("Initialize Catalog"));
950 add_prompt(ua, _("Verify Catalog"));
951 add_prompt(ua, _("Verify Volume to Catalog"));
952 add_prompt(ua, _("Verify Disk to Catalog"));
953 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
954 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
956 jcr->JobLevel = L_VERIFY_INIT;
959 jcr->JobLevel = L_VERIFY_CATALOG;
962 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
965 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
968 jcr->JobLevel = L_VERIFY_DATA;
974 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
979 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
980 char *jid, const char *replace)
982 Dmsg1(800, "JobType=%c\n", jcr->JobType);
983 switch (jcr->JobType) {
985 char dt[MAX_TIME_LENGTH];
987 if (ua->api) ua->signal(BNET_RUN_CMD);
988 ua->send_msg(_("Run %s job\n"
997 jcr->fileset->name(),
998 NPRT(jcr->client->name()),
999 jcr->wstore?jcr->wstore->name():"*None*",
1000 bstrutime(dt, sizeof(dt), jcr->sched_time),
1002 jcr->JobLevel = L_FULL;
1006 if (jcr->JobType == JT_BACKUP) {
1007 if (ua->api) ua->signal(BNET_RUN_CMD);
1008 ua->send_msg(_("Run %s job\n"
1013 "Pool: %s (From %s)\n"
1014 "Storage: %s (From %s)\n"
1019 level_to_str(jcr->JobLevel),
1020 jcr->client->name(),
1021 jcr->fileset->name(),
1022 NPRT(jcr->pool->name()), jcr->pool_source,
1023 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
1024 bstrutime(dt, sizeof(dt), jcr->sched_time),
1026 } else { /* JT_VERIFY */
1028 if (jcr->verify_job) {
1029 Name = jcr->verify_job->name();
1034 verify_list = job->WriteVerifyList;
1039 if (ua->api) ua->signal(BNET_RUN_CMD);
1040 ua->send_msg(_("Run %s job\n"
1045 "Pool: %s (From %s)\n"
1046 "Storage: %s (From %s)\n"
1053 level_to_str(jcr->JobLevel),
1054 jcr->client->name(),
1055 jcr->fileset->name(),
1056 NPRT(jcr->pool->name()), jcr->pool_source,
1057 jcr->rstore->name(), jcr->rstore_source,
1060 bstrutime(dt, sizeof(dt), jcr->sched_time),
1065 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
1067 jcr->RestoreJobId = str_to_int64(jid);
1069 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
1072 jcr->RestoreJobId = ua->int64_val;
1075 jcr->JobLevel = L_FULL; /* default level */
1076 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
1077 if (jcr->RestoreJobId == 0) {
1078 if (ua->api) ua->signal(BNET_RUN_CMD);
1079 ua->send_msg(_("Run Restore job\n"
1082 "%s %s\n" /* Where or RegexWhere */
1091 NPRT(jcr->RestoreBootstrap),
1092 jcr->where_use_regexp?"RegexWhere:":"Where: ",
1093 jcr->where?jcr->where:NPRT(job->RestoreWhere),
1095 jcr->fileset->name(),
1096 jcr->client->name(),
1097 jcr->rstore->name(),
1098 bstrutime(dt, sizeof(dt), jcr->sched_time),
1099 jcr->catalog->name(),
1102 if (ua->api) ua->signal(BNET_RUN_CMD);
1103 ua->send_msg(_("Run Restore job\n"
1106 "%s %s\n" /* Where or RegexWhere */
1115 NPRT(jcr->RestoreBootstrap),
1116 jcr->where_use_regexp?"RegexWhere:":"Where: ",
1117 jcr->where?jcr->where:NPRT(job->RestoreWhere),
1119 jcr->client->name(),
1120 jcr->rstore->name(),
1121 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
1122 bstrutime(dt, sizeof(dt), jcr->sched_time),
1123 jcr->catalog->name(),
1128 jcr->JobLevel = L_FULL; /* default level */
1129 if (ua->api) ua->signal(BNET_RUN_CMD);
1130 ua->send_msg(_("Run Migration job\n"
1135 "Pool: %s (From %s)\n"
1136 "Read Storage: %s (From %s)\n"
1137 "Write Storage: %s (From %s)\n"
1143 NPRT(jcr->RestoreBootstrap),
1144 jcr->client->name(),
1145 jcr->fileset->name(),
1146 NPRT(jcr->pool->name()), jcr->pool_source,
1147 jcr->rstore->name(), jcr->rstore_source,
1148 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
1149 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
1150 bstrutime(dt, sizeof(dt), jcr->sched_time),
1151 jcr->catalog->name(),
1155 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);