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, *regexwhere;
67 char *when, *verify_job_name, *catalog_name;
68 char *previous_job_name;
73 int i, j, opt, files = 0;
76 JOB *verify_job = NULL;
77 JOB *previous_job = NULL;
79 CLIENT *client = NULL;
80 FILESET *fileset = NULL;
82 static const char *kw[] = { /* command line arguments */
83 "job", /* Used in a switch() */
91 "regexwhere", /* 8 where string as a bregexp */
97 "yes", /* 14 -- if you change this change YES_POS too */
99 "files", /* 16 number of files to restore */
100 "catalog", /* 17 override catalog */
101 "since", /* 18 since */
102 "cloned", /* 19 cloned */
103 "verifylist", /* 20 verify output list */
104 "migrationjob", /* 21 migration job name */
110 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 */
195 if (regexwhere || where) {
196 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
199 regexwhere = ua->argv[i];
200 if (!acl_access_ok(ua, Where_ACL, regexwhere)) {
201 ua->send_msg(_("Forbidden \"regexwhere\" specified.\n"));
207 if (where || regexwhere) {
208 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
212 if (!acl_access_ok(ua, Where_ACL, where)) {
213 ua->send_msg(_("Forbidden \"where\" specified.\n"));
218 case 10: /* bootstrap */
220 ua->send_msg(_("Bootstrap specified twice.\n"));
223 bootstrap = ua->argv[i];
226 case 11: /* replace */
228 ua->send_msg(_("Replace specified twice.\n"));
231 replace = ua->argv[i];
236 ua->send_msg(_("When specified twice.\n"));
242 case 13: /* Priority */
244 ua->send_msg(_("Priority specified twice.\n"));
247 Priority = atoi(ua->argv[i]);
249 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
257 case 15: /* Verify Job */
258 if (verify_job_name) {
259 ua->send_msg(_("Verify Job specified twice.\n"));
262 verify_job_name = ua->argv[i];
266 files = atoi(ua->argv[i]);
270 case 17: /* catalog */
271 catalog_name = ua->argv[i];
280 case 19: /* cloned */
285 case 20: /* write verify list output */
286 verify_list = ua->argv[i];
289 case 21: /* Migration Job */
290 if (previous_job_name) {
291 ua->send_msg(_("Migration Job specified twice.\n"));
294 previous_job_name = ua->argv[i];
299 ua->send_msg(_("Pool specified twice.\n"));
302 pool_name = ua->argv[i];
309 } /* end strcase compare */
310 } /* end keyword loop */
312 * End of keyword for loop -- if not found, we got a bogus keyword
315 Dmsg1(800, "%s not found\n", ua->argk[i]);
317 * Special case for Job Name, it can be the first
318 * keyword that has no value.
320 if (!job_name && !ua->argv[i]) {
321 job_name = ua->argk[i]; /* use keyword as job name */
322 Dmsg1(800, "Set jobname=%s\n", job_name);
324 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
328 } /* end argc loop */
330 Dmsg0(800, "Done scan.\n");
333 if (catalog_name != NULL) {
334 catalog = (CAT *)GetResWithName(R_CATALOG, catalog_name);
335 if (catalog == NULL) {
336 ua->error_msg(_("Catalog \"%s\" not found\n"), catalog_name);
339 if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
340 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), catalog->name());
344 Dmsg1(800, "Using catalog=%s\n", NPRT(catalog_name));
348 job = (JOB *)GetResWithName(R_JOB, job_name);
350 if (*job_name != 0) {
351 ua->send_msg(_("Job \"%s\" not found\n"), job_name);
353 job = select_job_resource(ua);
355 Dmsg1(800, "Found job=%s\n", job_name);
358 ua->send_msg(_("A job name must be specified.\n"));
359 job = select_job_resource(ua);
363 } else if (!acl_access_ok(ua, Job_ACL, job->name())) {
364 ua->error_msg( _("No authorization. Job \"%s\".\n"),
370 pool = (POOL *)GetResWithName(R_POOL, pool_name);
372 if (*pool_name != 0) {
373 ua->warning_msg(_("Pool \"%s\" not found.\n"), pool_name);
375 pool = select_pool_resource(ua);
378 pool = job->pool; /* use default */
382 } else if (!acl_access_ok(ua, Pool_ACL, pool->name())) {
383 ua->error_msg(_("No authorization. Pool \"%s\".\n"),
387 Dmsg1(100, "Using pool %s\n", pool->name());
390 store.store = (STORE *)GetResWithName(R_STORAGE, store_name);
391 pm_strcpy(store.store_source, _("command line"));
393 if (*store_name != 0) {
394 ua->warning_msg(_("Storage \"%s\" not found.\n"), store_name);
396 store.store = select_storage_resource(ua);
397 pm_strcpy(store.store_source, _("user selection"));
400 get_job_storage(&store, job, NULL); /* use default */
403 ua->error_msg(_("No storage specified.\n"));
405 } else if (!acl_access_ok(ua, Storage_ACL, store.store->name())) {
406 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
407 store.store->name());
410 Dmsg1(800, "Using storage=%s\n", store.store->name());
413 client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
415 if (*client_name != 0) {
416 ua->warning_msg(_("Client \"%s\" not found.\n"), client_name);
418 client = select_client_resource(ua);
421 client = job->client; /* use default */
425 } else if (!acl_access_ok(ua, Client_ACL, client->name())) {
426 ua->error_msg(_("No authorization. Client \"%s\".\n"),
430 Dmsg1(800, "Using client=%s\n", client->name());
433 fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
435 ua->send_msg(_("FileSet \"%s\" not found.\n"), fileset_name);
436 fileset = select_fileset_resource(ua);
439 fileset = job->fileset; /* use default */
443 } else if (!acl_access_ok(ua, FileSet_ACL, fileset->name())) {
444 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
449 if (verify_job_name) {
450 verify_job = (JOB *)GetResWithName(R_JOB, verify_job_name);
452 ua->send_msg(_("Verify Job \"%s\" not found.\n"), verify_job_name);
453 verify_job = select_job_resource(ua);
456 verify_job = job->verify_job;
459 if (previous_job_name) {
460 previous_job = (JOB *)GetResWithName(R_JOB, previous_job_name);
462 ua->send_msg(_("Migration Job \"%s\" not found.\n"), previous_job_name);
463 previous_job = select_job_resource(ua);
466 previous_job = job->verify_job;
471 * Create JCR to run job. NOTE!!! after this point, free_jcr()
474 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
475 set_jcr_defaults(jcr, job);
476 jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */
477 ua->jcr->unlink_bsr = false;
479 jcr->verify_job = verify_job;
480 jcr->previous_job = previous_job;
482 set_rwstorage(jcr, &store);
483 jcr->client = client;
484 pm_strcpy(jcr->client_name, client->name());
485 jcr->fileset = fileset;
486 jcr->ExpectedFiles = files;
487 if (catalog != NULL) {
488 jcr->catalog = catalog;
494 jcr->where = bstrdup(where);
498 if (jcr->RegexWhere) {
499 free(jcr->RegexWhere);
501 jcr->RegexWhere = bstrdup(regexwhere);
505 jcr->sched_time = str_to_utime(when);
506 if (jcr->sched_time == 0) {
507 ua->send_msg(_("Invalid time, using current time.\n"));
508 jcr->sched_time = time(NULL);
513 if (jcr->RestoreBootstrap) {
514 free(jcr->RestoreBootstrap);
516 jcr->RestoreBootstrap = bstrdup(bootstrap);
521 for (i=0; ReplaceOptions[i].name; i++) {
522 if (strcasecmp(replace, ReplaceOptions[i].name) == 0) {
523 jcr->replace = ReplaceOptions[i].token;
527 ua->send_msg(_("Invalid replace option: %s\n"), replace);
530 } else if (job->replace) {
531 jcr->replace = job->replace;
533 jcr->replace = REPLACE_ALWAYS;
537 jcr->JobPriority = Priority;
542 jcr->stime = get_pool_memory(PM_MESSAGE);
544 pm_strcpy(jcr->stime, since);
547 jcr->cloned = cloned;
549 if (find_arg(ua, NT_("fdcalled")) > 0) {
550 jcr->file_bsock = dup_bsock(ua->UA_sock);
555 /* If pool changed, update migration write storage */
556 if (jcr->JobType == JT_MIGRATE) {
557 if (!set_migration_wstorage(jcr, pool)) {
561 replace = ReplaceOptions[0].name;
562 for (i=0; ReplaceOptions[i].name; i++) {
563 if (ReplaceOptions[i].token == jcr->replace) {
564 replace = ReplaceOptions[i].name;
568 if (!get_level_from_name(jcr, level_name)) {
569 ua->send_msg(_("Level %s not valid.\n"), level_name);
574 /* Note, this is also MigrateJobId */
575 jcr->RestoreJobId = str_to_int64(jid);
578 /* Run without prompting? */
579 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
584 * Prompt User to see if all run job parameters are correct, and
585 * allow him to modify them.
587 if (!display_job_parameters(ua, jcr, job, verify_list, jid, replace)) {
591 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
596 * At user request modify parameters of job to be run.
598 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
601 start_prompt(ua, _("Parameters to modify:\n"));
602 add_prompt(ua, _("Level")); /* 0 */
603 add_prompt(ua, _("Storage")); /* 1 */
604 add_prompt(ua, _("Job")); /* 2 */
605 add_prompt(ua, _("FileSet")); /* 3 */
606 add_prompt(ua, _("Client")); /* 4 */
607 add_prompt(ua, _("When")); /* 5 */
608 add_prompt(ua, _("Priority")); /* 6 */
609 if (jcr->JobType == JT_BACKUP ||
610 jcr->JobType == JT_MIGRATE ||
611 jcr->JobType == JT_VERIFY) {
612 add_prompt(ua, _("Pool")); /* 7 */
613 if (jcr->JobType == JT_VERIFY) {
614 add_prompt(ua, _("Verify Job")); /* 8 */
616 } else if (jcr->JobType == JT_RESTORE) {
617 add_prompt(ua, _("Bootstrap")); /* 7 */
618 add_prompt(ua, _("Where")); /* 8 */
619 add_prompt(ua, _("File Relocation"));/* 9 */
620 add_prompt(ua, _("Replace")); /* 10 */
621 add_prompt(ua, _("JobId")); /* 11 */
623 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
626 select_job_level(ua, jcr);
630 store.store = select_storage_resource(ua);
632 pm_strcpy(store.store_source, _("user selection"));
633 set_rwstorage(jcr, &store);
639 job = select_job_resource(ua);
642 set_jcr_defaults(jcr, job);
648 fileset = select_fileset_resource(ua);
650 jcr->fileset = fileset;
656 client = select_client_resource(ua);
658 jcr->client = client;
664 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
667 if (ua->cmd[0] == 0) {
668 jcr->sched_time = time(NULL);
670 jcr->sched_time = str_to_utime(ua->cmd);
671 if (jcr->sched_time == 0) {
672 ua->send_msg(_("Invalid time, using current time.\n"));
673 jcr->sched_time = time(NULL);
679 if (!get_pint(ua, _("Enter new Priority: "))) {
682 if (ua->pint32_val == 0) {
683 ua->send_msg(_("Priority must be a positive integer.\n"));
685 jcr->JobPriority = ua->pint32_val;
689 /* Pool or Bootstrap depending on JobType */
690 if (jcr->JobType == JT_BACKUP ||
691 jcr->JobType == JT_MIGRATE ||
692 jcr->JobType == JT_VERIFY) { /* Pool */
693 pool = select_pool_resource(ua);
696 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
703 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
706 if (jcr->RestoreBootstrap) {
707 free(jcr->RestoreBootstrap);
708 jcr->RestoreBootstrap = NULL;
710 if (ua->cmd[0] != 0) {
711 jcr->RestoreBootstrap = bstrdup(ua->cmd);
712 fd = fopen(jcr->RestoreBootstrap, "rb");
714 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
715 jcr->RestoreBootstrap, strerror(errno));
716 free(jcr->RestoreBootstrap);
717 jcr->RestoreBootstrap = NULL;
725 if (jcr->JobType == JT_VERIFY) {
726 verify_job = select_job_resource(ua);
728 jcr->verify_job = verify_job;
733 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
736 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
737 free(jcr->RegexWhere);
738 jcr->RegexWhere = NULL;
744 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
747 jcr->where = bstrdup(ua->cmd);
750 /* File relocation */
751 select_where_regexp(ua, jcr);
755 start_prompt(ua, _("Replace:\n"));
756 for (i=0; ReplaceOptions[i].name; i++) {
757 add_prompt(ua, ReplaceOptions[i].name);
759 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
761 jcr->replace = ReplaceOptions[opt].token;
766 jid = NULL; /* force reprompt */
767 jcr->RestoreJobId = 0;
768 if (jcr->RestoreBootstrap) {
769 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
772 case -1: /* error or cancel */
780 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
782 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
784 Dmsg1(100, "Using pool %s\n", jcr->pool->name());
785 JobId = run_job(jcr);
787 ua->send_msg("<job director=\"console\" time=\"%u\" status=\"%c\" type=\"%c\" "
788 "jobid=\"%u\" job=\"%s\" level=\"%c\" finished=\"false\" priority=\"%u\"/>\n",
789 time(NULL), jcr->JobStatus, jcr->JobType, jcr->JobId,
790 jcr->Job, jcr->JobLevel, jcr->JobPriority);
792 free_jcr(jcr); /* release jcr */
794 ua->error_msg(_("Job failed.\n"));
797 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId,ed1));
803 ua->send_msg(_("Job not run.\n"));
805 return 0; /* do not run */
808 static void select_where_regexp(UAContext *ua, JCR *jcr)
811 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
812 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
815 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
816 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
818 start_prompt(ua, _("This will replace your current Where value\n"));
819 add_prompt(ua, _("Strip prefix")); /* 0 */
820 add_prompt(ua, _("Add prefix")); /* 1 */
821 add_prompt(ua, _("Add file suffix")); /* 2 */
822 add_prompt(ua, _("Enter a regexp")); /* 3 */
823 add_prompt(ua, _("Test filename manipulation")); /* 4 */
824 add_prompt(ua, _("Use this ?")); /* 5 */
826 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
829 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
830 if (strip_prefix) bfree(strip_prefix);
831 strip_prefix = bstrdup(ua->cmd);
837 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
838 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
842 if (add_prefix) bfree(add_prefix);
843 add_prefix = bstrdup(ua->cmd);
848 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
849 if (add_suffix) bfree(add_suffix);
850 add_suffix = bstrdup(ua->cmd);
855 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
856 if (rwhere) bfree(rwhere);
857 rwhere = bstrdup(ua->cmd);
866 if (rwhere && rwhere[0] != '\0') {
867 regs = get_bregexps(rwhere);
868 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
870 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
871 regexp = (char *) bmalloc (len * sizeof(char));
872 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
873 regs = get_bregexps(regexp);
874 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
875 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
881 ua->send_msg(_("Cannot use your regexp\n"));
885 while (get_cmd(ua, _("Please enter filename to test: "))) {
886 apply_bregexps(ua->cmd, regs, &result);
887 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
896 case -1: /* error or cancel */
902 /* replace the existing where */
908 /* replace the existing regexwhere */
909 if (jcr->RegexWhere) {
910 bfree(jcr->RegexWhere);
911 jcr->RegexWhere = NULL;
915 jcr->RegexWhere = bstrdup(rwhere);
916 } else if (strip_prefix || add_prefix || add_suffix) {
917 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
918 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
919 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
922 regs = get_bregexps(jcr->RegexWhere);
927 if (jcr->RegexWhere) {
928 bfree(jcr->RegexWhere);
929 jcr->RegexWhere = NULL;
931 ua->send_msg(_("Cannot use your regexp.\n"));
935 if (strip_prefix) bfree(strip_prefix);
936 if (add_prefix) bfree(add_prefix);
937 if (add_suffix) bfree(add_suffix);
938 if (rwhere) bfree(rwhere);
941 static void select_job_level(UAContext *ua, JCR *jcr)
943 if (jcr->JobType == JT_BACKUP) {
944 start_prompt(ua, _("Levels:\n"));
945 add_prompt(ua, _("Base"));
946 add_prompt(ua, _("Full"));
947 add_prompt(ua, _("Incremental"));
948 add_prompt(ua, _("Differential"));
949 add_prompt(ua, _("Since"));
950 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
952 jcr->JobLevel = L_BASE;
955 jcr->JobLevel = L_FULL;
958 jcr->JobLevel = L_INCREMENTAL;
961 jcr->JobLevel = L_DIFFERENTIAL;
964 jcr->JobLevel = L_SINCE;
969 } else if (jcr->JobType == JT_VERIFY) {
970 start_prompt(ua, _("Levels:\n"));
971 add_prompt(ua, _("Initialize Catalog"));
972 add_prompt(ua, _("Verify Catalog"));
973 add_prompt(ua, _("Verify Volume to Catalog"));
974 add_prompt(ua, _("Verify Disk to Catalog"));
975 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
976 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
978 jcr->JobLevel = L_VERIFY_INIT;
981 jcr->JobLevel = L_VERIFY_CATALOG;
984 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
987 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
990 jcr->JobLevel = L_VERIFY_DATA;
996 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
1001 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, char *verify_list,
1002 char *jid, const char *replace)
1004 Dmsg1(800, "JobType=%c\n", jcr->JobType);
1005 switch (jcr->JobType) {
1007 char dt[MAX_TIME_LENGTH];
1009 if (ua->api) ua->signal(BNET_RUN_CMD);
1010 ua->send_msg(_("Run %s job\n"
1019 jcr->fileset->name(),
1020 NPRT(jcr->client->name()),
1021 jcr->wstore?jcr->wstore->name():"*None*",
1022 bstrutime(dt, sizeof(dt), jcr->sched_time),
1024 jcr->JobLevel = L_FULL;
1028 if (jcr->JobType == JT_BACKUP) {
1029 if (ua->api) ua->signal(BNET_RUN_CMD);
1030 ua->send_msg(_("Run %s job\n"
1035 "Pool: %s (From %s)\n"
1036 "Storage: %s (From %s)\n"
1041 level_to_str(jcr->JobLevel),
1042 jcr->client->name(),
1043 jcr->fileset->name(),
1044 NPRT(jcr->pool->name()), jcr->pool_source,
1045 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
1046 bstrutime(dt, sizeof(dt), jcr->sched_time),
1048 } else { /* JT_VERIFY */
1050 if (jcr->verify_job) {
1051 Name = jcr->verify_job->name();
1056 verify_list = job->WriteVerifyList;
1061 if (ua->api) ua->signal(BNET_RUN_CMD);
1062 ua->send_msg(_("Run %s job\n"
1067 "Pool: %s (From %s)\n"
1068 "Storage: %s (From %s)\n"
1075 level_to_str(jcr->JobLevel),
1076 jcr->client->name(),
1077 jcr->fileset->name(),
1078 NPRT(jcr->pool->name()), jcr->pool_source,
1079 jcr->rstore->name(), jcr->rstore_source,
1082 bstrutime(dt, sizeof(dt), jcr->sched_time),
1087 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
1089 jcr->RestoreJobId = str_to_int64(jid);
1091 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
1094 jcr->RestoreJobId = ua->int64_val;
1097 jcr->JobLevel = L_FULL; /* default level */
1098 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
1099 if (jcr->RestoreJobId == 0) {
1100 if (ua->api) ua->signal(BNET_RUN_CMD);
1101 ua->send_msg(_("Run Restore job\n"
1105 NPRT(jcr->RestoreBootstrap));
1107 /* RegexWhere is take before RestoreWhere */
1108 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
1109 ua->send_msg(_("RegexWhere: %s\n"),
1110 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
1112 ua->send_msg(_("Where: %s\n"),
1113 jcr->where?jcr->where:NPRT(job->RestoreWhere));
1116 ua->send_msg(_("Replace: %s\n"
1124 jcr->fileset->name(),
1125 jcr->client->name(),
1126 jcr->rstore->name(),
1127 bstrutime(dt, sizeof(dt), jcr->sched_time),
1128 jcr->catalog->name(),
1131 if (ua->api) ua->signal(BNET_RUN_CMD);
1132 ua->send_msg(_("Run Restore job\n"
1136 NPRT(jcr->RestoreBootstrap));
1138 /* RegexWhere is take before RestoreWhere */
1139 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
1140 ua->send_msg(_("RegexWhere: %s\n"),
1141 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
1143 ua->send_msg(_("Where: %s\n"),
1144 jcr->where?jcr->where:NPRT(job->RestoreWhere));
1147 ua->send_msg(_("Replace: %s\n"
1155 jcr->client->name(),
1156 jcr->rstore->name(),
1157 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
1158 bstrutime(dt, sizeof(dt), jcr->sched_time),
1159 jcr->catalog->name(),
1164 jcr->JobLevel = L_FULL; /* default level */
1165 if (ua->api) ua->signal(BNET_RUN_CMD);
1166 ua->send_msg(_("Run Migration job\n"
1171 "Pool: %s (From %s)\n"
1172 "Read Storage: %s (From %s)\n"
1173 "Write Storage: %s (From %s)\n"
1179 NPRT(jcr->RestoreBootstrap),
1180 jcr->client->name(),
1181 jcr->fileset->name(),
1182 NPRT(jcr->pool->name()), jcr->pool_source,
1183 jcr->rstore->name(), jcr->rstore_source,
1184 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
1185 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
1186 bstrutime(dt, sizeof(dt), jcr->sched_time),
1187 jcr->catalog->name(),
1191 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);