2 Bacula® - The Network Backup Solution
4 Copyright (C) 2001-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- Run Command
32 * Kern Sibbald, December MMI
42 char *job_name, *level_name, *jid, *store_name, *pool_name;
43 char *where, *fileset_name, *client_name, *bootstrap, *regexwhere;
44 char *restore_client_name;
46 char *when, *verify_job_name, *catalog_name;
47 char *previous_job_name;
49 const char *verify_list;
64 run_ctx() { memset(this, 0, sizeof(run_ctx));
65 store = new USTORE; };
66 ~run_ctx() { delete store; };
69 /* Forward referenced subroutines */
70 static void select_job_level(UAContext *ua, JCR *jcr);
71 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job,
72 const char *verify_list, char *jid, const char *replace,
74 static void select_where_regexp(UAContext *ua, JCR *jcr);
75 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc);
77 /* Imported variables */
78 extern struct s_kw ReplaceOptions[];
81 * For Backup and Verify Jobs
82 * run [job=]<job-name> level=<level-name>
91 int run_cmd(UAContext *ua, const char *cmd)
97 if (!open_client_db(ua)) {
101 if (!scan_command_line_arguments(ua, rc)) {
105 if (find_arg(ua, NT_("fdcalled")) > 0) {
106 jcr->file_bsock = dup_bsock(ua->UA_sock);
112 * Create JCR to run job. NOTE!!! after this point, free_jcr()
116 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
117 set_jcr_defaults(jcr, rc.job);
118 jcr->unlink_bsr = ua->jcr->unlink_bsr; /* copy unlink flag from caller */
119 ua->jcr->unlink_bsr = false;
122 jcr->verify_job = rc.verify_job;
123 jcr->previous_job = rc.previous_job;
125 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;
140 jcr->where = bstrdup(rc.where);
145 if (jcr->RegexWhere) {
146 free(jcr->RegexWhere);
148 jcr->RegexWhere = bstrdup(rc.regexwhere);
149 rc.regexwhere = NULL;
153 jcr->sched_time = str_to_utime(rc.when);
154 if (jcr->sched_time == 0) {
155 ua->send_msg(_("Invalid time, using current time.\n"));
156 jcr->sched_time = time(NULL);
162 if (jcr->RestoreBootstrap) {
163 free(jcr->RestoreBootstrap);
165 jcr->RestoreBootstrap = bstrdup(rc.bootstrap);
171 for (i=0; ReplaceOptions[i].name; i++) {
172 if (strcasecmp(rc.replace, ReplaceOptions[i].name) == 0) {
173 jcr->replace = ReplaceOptions[i].token;
177 ua->send_msg(_("Invalid replace option: %s\n"), rc.replace);
180 } else if (rc.job->replace) {
181 jcr->replace = rc.job->replace;
183 jcr->replace = REPLACE_ALWAYS;
188 jcr->JobPriority = rc.Priority;
194 jcr->stime = get_pool_memory(PM_MESSAGE);
196 pm_strcpy(jcr->stime, rc.since);
201 jcr->cloned = rc.cloned;
206 /* If pool changed, update migration write storage */
207 if (jcr->JobType == JT_MIGRATE) {
208 if (!set_migration_wstorage(jcr, rc.pool)) {
212 rc.replace = ReplaceOptions[0].name;
213 for (i=0; ReplaceOptions[i].name; i++) {
214 if (ReplaceOptions[i].token == jcr->replace) {
215 rc.replace = ReplaceOptions[i].name;
219 if (!get_level_from_name(jcr, rc.level_name)) {
220 ua->send_msg(_("Level %s not valid.\n"), rc.level_name);
223 rc.level_name = NULL;
226 /* Note, this is also MigrateJobId */
227 jcr->RestoreJobId = str_to_int64(rc.jid);
231 /* Run without prompting? */
232 if (ua->batch || find_arg(ua, NT_("yes")) > 0) {
237 * Prompt User to see if all run job parameters are correct, and
238 * allow him to modify them.
240 if (!display_job_parameters(ua, jcr, rc.job, rc.verify_list, rc.jid, rc.replace,
245 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
249 if (strncasecmp(ua->cmd, ".mod ", 5) == 0 ||
250 (strncasecmp(ua->cmd, "mod ", 4) == 0 && strlen(ua->cmd) > 6)) {
253 if (!scan_command_line_arguments(ua, rc)) {
260 * At user request modify parameters of job to be run.
262 if (ua->cmd[0] != 0 && strncasecmp(ua->cmd, _("mod"), strlen(ua->cmd)) == 0) {
265 start_prompt(ua, _("Parameters to modify:\n"));
266 add_prompt(ua, _("Level")); /* 0 */
267 add_prompt(ua, _("Storage")); /* 1 */
268 add_prompt(ua, _("Job")); /* 2 */
269 add_prompt(ua, _("FileSet")); /* 3 */
270 if (jcr->JobType == JT_RESTORE) {
271 add_prompt(ua, _("Restore Client")); /* 4 */
273 add_prompt(ua, _("Client")); /* 4 */
275 add_prompt(ua, _("When")); /* 5 */
276 add_prompt(ua, _("Priority")); /* 6 */
277 if (jcr->JobType == JT_BACKUP ||
278 jcr->JobType == JT_MIGRATE ||
279 jcr->JobType == JT_VERIFY) {
280 add_prompt(ua, _("Pool")); /* 7 */
281 if (jcr->JobType == JT_VERIFY) {
282 add_prompt(ua, _("Verify Job")); /* 8 */
284 } else if (jcr->JobType == JT_RESTORE) {
285 add_prompt(ua, _("Bootstrap")); /* 7 */
286 add_prompt(ua, _("Where")); /* 8 */
287 add_prompt(ua, _("File Relocation"));/* 9 */
288 add_prompt(ua, _("Replace")); /* 10 */
289 add_prompt(ua, _("JobId")); /* 11 */
291 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
294 select_job_level(ua, jcr);
298 rc.store->store = select_storage_resource(ua);
299 if (rc.store->store) {
300 pm_strcpy(rc.store->store_source, _("user selection"));
301 set_rwstorage(jcr, rc.store);
307 rc.job = select_job_resource(ua);
310 set_jcr_defaults(jcr, rc.job);
316 rc.fileset = select_fileset_resource(ua);
318 jcr->fileset = rc.fileset;
324 rc.client = select_client_resource(ua);
326 jcr->client = rc.client;
332 if (!get_cmd(ua, _("Please enter desired start time as YYYY-MM-DD HH:MM:SS (return for now): "))) {
335 if (ua->cmd[0] == 0) {
336 jcr->sched_time = time(NULL);
338 jcr->sched_time = str_to_utime(ua->cmd);
339 if (jcr->sched_time == 0) {
340 ua->send_msg(_("Invalid time, using current time.\n"));
341 jcr->sched_time = time(NULL);
347 if (!get_pint(ua, _("Enter new Priority: "))) {
350 if (ua->pint32_val == 0) {
351 ua->send_msg(_("Priority must be a positive integer.\n"));
353 jcr->JobPriority = ua->pint32_val;
357 /* Pool or Bootstrap depending on JobType */
358 if (jcr->JobType == JT_BACKUP ||
359 jcr->JobType == JT_MIGRATE ||
360 jcr->JobType == JT_VERIFY) { /* Pool */
361 rc.pool = select_pool_resource(ua);
364 Dmsg1(100, "Set new pool=%s\n", jcr->pool->name());
371 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
374 if (jcr->RestoreBootstrap) {
375 free(jcr->RestoreBootstrap);
376 jcr->RestoreBootstrap = NULL;
378 if (ua->cmd[0] != 0) {
379 jcr->RestoreBootstrap = bstrdup(ua->cmd);
380 fd = fopen(jcr->RestoreBootstrap, "rb");
383 ua->send_msg(_("Warning cannot open %s: ERR=%s\n"),
384 jcr->RestoreBootstrap, be.bstrerror());
385 free(jcr->RestoreBootstrap);
386 jcr->RestoreBootstrap = NULL;
394 if (jcr->JobType == JT_VERIFY) {
395 rc.verify_job = select_job_resource(ua);
397 jcr->verify_job = rc.verify_job;
402 if (!get_cmd(ua, _("Please enter path prefix for restore (/ for none): "))) {
405 if (jcr->RegexWhere) { /* cannot use regexwhere and where */
406 free(jcr->RegexWhere);
407 jcr->RegexWhere = NULL;
413 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
416 jcr->where = bstrdup(ua->cmd);
419 /* File relocation */
420 select_where_regexp(ua, jcr);
424 start_prompt(ua, _("Replace:\n"));
425 for (i=0; ReplaceOptions[i].name; i++) {
426 add_prompt(ua, ReplaceOptions[i].name);
428 opt = do_prompt(ua, "", _("Select replace option"), NULL, 0);
430 rc.replace = ReplaceOptions[opt].name;
431 jcr->replace = ReplaceOptions[opt].token;
436 rc.jid = NULL; /* force reprompt */
437 jcr->RestoreJobId = 0;
438 if (jcr->RestoreBootstrap) {
439 ua->send_msg(_("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
442 case -1: /* error or cancel */
450 if (ua->cmd[0] == 0 || strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
452 Dmsg1(800, "Calling run_job job=%x\n", jcr->job);
455 Dmsg3(100, "JobId=%u using pool %s priority=%d\n", (int)jcr->JobId,
456 jcr->pool->name(), jcr->JobPriority);
457 JobId = run_job(jcr);
458 Dmsg4(100, "JobId=%u NewJobId=%d using pool %s priority=%d\n", (int)jcr->JobId,
459 JobId, jcr->pool->name(), jcr->JobPriority);
460 free_jcr(jcr); /* release jcr */
462 ua->error_msg(_("Job failed.\n"));
465 ua->send_msg(_("Job queued. JobId=%s\n"), edit_int64(JobId, ed1));
471 ua->send_msg(_("Job not run.\n"));
473 return 0; /* do not run */
476 static void select_where_regexp(UAContext *ua, JCR *jcr)
479 char *strip_prefix, *add_prefix, *add_suffix, *rwhere;
480 strip_prefix = add_suffix = rwhere = add_prefix = NULL;
483 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s\n"),
484 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix));
486 start_prompt(ua, _("This will replace your current Where value\n"));
487 add_prompt(ua, _("Strip prefix")); /* 0 */
488 add_prompt(ua, _("Add prefix")); /* 1 */
489 add_prompt(ua, _("Add file suffix")); /* 2 */
490 add_prompt(ua, _("Enter a regexp")); /* 3 */
491 add_prompt(ua, _("Test filename manipulation")); /* 4 */
492 add_prompt(ua, _("Use this ?")); /* 5 */
494 switch (do_prompt(ua, "", _("Select parameter to modify"), NULL, 0)) {
497 if (get_cmd(ua, _("Please enter path prefix to strip: "))) {
498 if (strip_prefix) bfree(strip_prefix);
499 strip_prefix = bstrdup(ua->cmd);
505 if (get_cmd(ua, _("Please enter path prefix to add (/ for none): "))) {
506 if (IsPathSeparator(ua->cmd[0]) && ua->cmd[1] == '\0') {
510 if (add_prefix) bfree(add_prefix);
511 add_prefix = bstrdup(ua->cmd);
516 if (get_cmd(ua, _("Please enter file suffix to add: "))) {
517 if (add_suffix) bfree(add_suffix);
518 add_suffix = bstrdup(ua->cmd);
523 if (get_cmd(ua, _("Please enter a valid regexp (!from!to!): "))) {
524 if (rwhere) bfree(rwhere);
525 rwhere = bstrdup(ua->cmd);
534 if (rwhere && rwhere[0] != '\0') {
535 regs = get_bregexps(rwhere);
536 ua->send_msg(_("regexwhere=%s\n"), NPRT(rwhere));
538 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
539 regexp = (char *) bmalloc (len * sizeof(char));
540 bregexp_build_where(regexp, len, strip_prefix, add_prefix, add_suffix);
541 regs = get_bregexps(regexp);
542 ua->send_msg(_("strip_prefix=%s add_prefix=%s add_suffix=%s result=%s\n"),
543 NPRT(strip_prefix), NPRT(add_prefix), NPRT(add_suffix), NPRT(regexp));
549 ua->send_msg(_("Cannot use your regexp\n"));
553 while (get_cmd(ua, _("Please enter filename to test: "))) {
554 apply_bregexps(ua->cmd, regs, &result);
555 ua->send_msg(_("%s -> %s\n"), ua->cmd, result);
564 case -1: /* error or cancel */
570 /* replace the existing where */
576 /* replace the existing regexwhere */
577 if (jcr->RegexWhere) {
578 bfree(jcr->RegexWhere);
579 jcr->RegexWhere = NULL;
583 jcr->RegexWhere = bstrdup(rwhere);
584 } else if (strip_prefix || add_prefix || add_suffix) {
585 int len = bregexp_get_build_where_size(strip_prefix, add_prefix, add_suffix);
586 jcr->RegexWhere = (char *) bmalloc(len*sizeof(char));
587 bregexp_build_where(jcr->RegexWhere, len, strip_prefix, add_prefix, add_suffix);
590 regs = get_bregexps(jcr->RegexWhere);
595 if (jcr->RegexWhere) {
596 bfree(jcr->RegexWhere);
597 jcr->RegexWhere = NULL;
599 ua->send_msg(_("Cannot use your regexp.\n"));
603 if (strip_prefix) bfree(strip_prefix);
604 if (add_prefix) bfree(add_prefix);
605 if (add_suffix) bfree(add_suffix);
606 if (rwhere) bfree(rwhere);
609 static void select_job_level(UAContext *ua, JCR *jcr)
611 if (jcr->JobType == JT_BACKUP) {
612 start_prompt(ua, _("Levels:\n"));
613 add_prompt(ua, _("Base"));
614 add_prompt(ua, _("Full"));
615 add_prompt(ua, _("Incremental"));
616 add_prompt(ua, _("Differential"));
617 add_prompt(ua, _("Since"));
618 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
620 jcr->JobLevel = L_BASE;
623 jcr->JobLevel = L_FULL;
626 jcr->JobLevel = L_INCREMENTAL;
629 jcr->JobLevel = L_DIFFERENTIAL;
632 jcr->JobLevel = L_SINCE;
637 } else if (jcr->JobType == JT_VERIFY) {
638 start_prompt(ua, _("Levels:\n"));
639 add_prompt(ua, _("Initialize Catalog"));
640 add_prompt(ua, _("Verify Catalog"));
641 add_prompt(ua, _("Verify Volume to Catalog"));
642 add_prompt(ua, _("Verify Disk to Catalog"));
643 add_prompt(ua, _("Verify Volume Data (not yet implemented)"));
644 switch (do_prompt(ua, "", _("Select level"), NULL, 0)) {
646 jcr->JobLevel = L_VERIFY_INIT;
649 jcr->JobLevel = L_VERIFY_CATALOG;
652 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
655 jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
658 jcr->JobLevel = L_VERIFY_DATA;
664 ua->warning_msg(_("Level not appropriate for this Job. Cannot be changed.\n"));
669 static bool display_job_parameters(UAContext *ua, JCR *jcr, JOB *job, const char *verify_list,
670 char *jid, const char *replace, char *client_name)
672 Dmsg1(800, "JobType=%c\n", jcr->JobType);
673 switch (jcr->JobType) {
675 char dt[MAX_TIME_LENGTH];
677 if (ua->api) ua->signal(BNET_RUN_CMD);
678 ua->send_msg(_("Run %s job\n"
687 jcr->fileset->name(),
688 NPRT(jcr->client->name()),
689 jcr->wstore?jcr->wstore->name():"*None*",
690 bstrutime(dt, sizeof(dt), jcr->sched_time),
692 jcr->JobLevel = L_FULL;
696 if (jcr->JobType == JT_BACKUP) {
697 if (ua->api) ua->signal(BNET_RUN_CMD);
698 ua->send_msg(_("Run %s job\n"
703 "Pool: %s (From %s)\n"
704 "Storage: %s (From %s)\n"
709 level_to_str(jcr->JobLevel),
711 jcr->fileset->name(),
712 NPRT(jcr->pool->name()), jcr->pool_source,
713 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
714 bstrutime(dt, sizeof(dt), jcr->sched_time),
716 } else { /* JT_VERIFY */
718 if (jcr->verify_job) {
719 Name = jcr->verify_job->name();
724 verify_list = job->WriteVerifyList;
729 if (ua->api) ua->signal(BNET_RUN_CMD);
730 ua->send_msg(_("Run %s job\n"
735 "Pool: %s (From %s)\n"
736 "Storage: %s (From %s)\n"
743 level_to_str(jcr->JobLevel),
745 jcr->fileset->name(),
746 NPRT(jcr->pool->name()), jcr->pool_source,
747 jcr->rstore->name(), jcr->rstore_source,
750 bstrutime(dt, sizeof(dt), jcr->sched_time),
755 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
757 jcr->RestoreJobId = str_to_int64(jid);
759 if (!get_pint(ua, _("Please enter a JobId for restore: "))) {
762 jcr->RestoreJobId = ua->int64_val;
765 jcr->JobLevel = L_FULL; /* default level */
766 Dmsg1(800, "JobId to restore=%d\n", jcr->RestoreJobId);
767 if (jcr->RestoreJobId == 0) {
768 if (ua->api) ua->signal(BNET_RUN_CMD);
769 /* RegexWhere is take before RestoreWhere */
770 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
771 ua->send_msg(_("Run Restore job\n"
777 "Backup Client: %s\n"
778 "Restore Client: %s\n"
784 NPRT(jcr->RestoreBootstrap),
785 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere,
787 jcr->fileset->name(),
791 bstrutime(dt, sizeof(dt), jcr->sched_time),
792 jcr->catalog->name(),
796 ua->send_msg(_("Run Restore job\n"
802 "Backup Client: %s\n"
803 "Restore Client: %s\n"
809 NPRT(jcr->RestoreBootstrap),
810 jcr->where?jcr->where:NPRT(job->RestoreWhere),
812 jcr->fileset->name(),
816 bstrutime(dt, sizeof(dt), jcr->sched_time),
817 jcr->catalog->name(),
822 if (ua->api) ua->signal(BNET_RUN_CMD);
823 ua->send_msg(_("Run Restore job\n"
827 NPRT(jcr->RestoreBootstrap));
829 /* RegexWhere is take before RestoreWhere */
830 if (jcr->RegexWhere || (job->RegexWhere && !jcr->where)) {
831 ua->send_msg(_("RegexWhere: %s\n"),
832 jcr->RegexWhere?jcr->RegexWhere:job->RegexWhere);
834 ua->send_msg(_("Where: %s\n"),
835 jcr->where?jcr->where:NPRT(job->RestoreWhere));
838 ua->send_msg(_("Replace: %s\n"
848 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1),
849 bstrutime(dt, sizeof(dt), jcr->sched_time),
850 jcr->catalog->name(),
855 jcr->JobLevel = L_FULL; /* default level */
856 if (ua->api) ua->signal(BNET_RUN_CMD);
857 ua->send_msg(_("Run Migration job\n"
862 "Pool: %s (From %s)\n"
863 "Read Storage: %s (From %s)\n"
864 "Write Storage: %s (From %s)\n"
870 NPRT(jcr->RestoreBootstrap),
872 jcr->fileset->name(),
873 NPRT(jcr->pool->name()), jcr->pool_source,
874 jcr->rstore->name(), jcr->rstore_source,
875 jcr->wstore?jcr->wstore->name():"*None*", jcr->wstore_source,
876 jcr->MigrateJobId==0?"*None*":edit_uint64(jcr->MigrateJobId, ec1),
877 bstrutime(dt, sizeof(dt), jcr->sched_time),
878 jcr->catalog->name(),
882 ua->error_msg(_("Unknown Job Type=%d\n"), jcr->JobType);
889 static bool scan_command_line_arguments(UAContext *ua, run_ctx &rc)
893 static const char *kw[] = { /* command line arguments */
894 "job", /* Used in a switch() */
902 "regexwhere", /* 8 where string as a bregexp */
904 "bootstrap", /* 10 */
908 "yes", /* 14 -- if you change this change YES_POS too */
909 "verifyjob", /* 15 */
910 "files", /* 16 number of files to restore */
911 "catalog", /* 17 override catalog */
912 "since", /* 18 since */
913 "cloned", /* 19 cloned */
914 "verifylist", /* 20 verify output list */
915 "migrationjob", /* 21 migration job name */
917 "backupclient", /* 23 */
918 "restoreclient", /* 24 */
923 rc.catalog_name = NULL;
926 rc.store_name = NULL;
927 rc.client_name = NULL;
928 rc.restore_client_name = NULL;
929 rc.fileset_name = NULL;
930 rc.verify_job_name = NULL;
931 rc.previous_job_name = NULL;
934 for (i=1; i<ua->argc; i++) {
935 Dmsg2(800, "Doing arg %d = %s\n", i, ua->argk[i]);
937 /* Keep looking until we find a good keyword */
938 for (j=0; !kw_ok && kw[j]; j++) {
939 if (strcasecmp(ua->argk[i], kw[j]) == 0) {
940 /* Note, yes and run have no value, so do not fail */
941 if (!ua->argv[i] && j != YES_POS /*yes*/) {
942 ua->send_msg(_("Value missing for keyword %s\n"), ua->argk[i]);
945 Dmsg1(800, "Got keyword=%s\n", NPRT(kw[j]));
949 ua->send_msg(_("Job name specified twice.\n"));
952 rc.job_name = ua->argv[i];
956 if (rc.jid && !rc.mod) {
957 ua->send_msg(_("JobId specified twice.\n"));
960 rc.jid = ua->argv[i];
965 if (rc.client_name) {
966 ua->send_msg(_("Client specified twice.\n"));
969 rc.client_name = ua->argv[i];
972 case 4: /* fileset */
973 if (rc.fileset_name) {
974 ua->send_msg(_("FileSet specified twice.\n"));
977 rc.fileset_name = ua->argv[i];
982 ua->send_msg(_("Level specified twice.\n"));
985 rc.level_name = ua->argv[i];
988 case 6: /* storage */
991 ua->send_msg(_("Storage specified twice.\n"));
994 rc.store_name = ua->argv[i];
997 case 8: /* regexwhere */
998 if ((rc.regexwhere || rc.where) && !rc.mod) {
999 ua->send_msg(_("RegexWhere or Where specified twice.\n"));
1002 rc.regexwhere = ua->argv[i];
1003 if (!acl_access_ok(ua, Where_ACL, rc.regexwhere)) {
1004 ua->send_msg(_("No authorization for \"regexwhere\" specification.\n"));
1010 if ((rc.where || rc.regexwhere) && !rc.mod) {
1011 ua->send_msg(_("Where or RegexWhere specified twice.\n"));
1014 rc.where = ua->argv[i];
1015 if (!acl_access_ok(ua, Where_ACL, rc.where)) {
1016 ua->send_msg(_("No authoriztion for \"where\" specification.\n"));
1021 case 10: /* bootstrap */
1022 if (rc.bootstrap && !rc.mod) {
1023 ua->send_msg(_("Bootstrap specified twice.\n"));
1026 rc.bootstrap = ua->argv[i];
1029 case 11: /* replace */
1030 if (rc.replace && !rc.mod) {
1031 ua->send_msg(_("Replace specified twice.\n"));
1034 rc.replace = ua->argv[i];
1038 if (rc.when && !rc.mod) {
1039 ua->send_msg(_("When specified twice.\n"));
1042 rc.when = ua->argv[i];
1045 case 13: /* Priority */
1046 if (rc.Priority && !rc.mod) {
1047 ua->send_msg(_("Priority specified twice.\n"));
1050 rc.Priority = atoi(ua->argv[i]);
1051 if (rc.Priority <= 0) {
1052 ua->send_msg(_("Priority must be positive nonzero setting it to 10.\n"));
1060 case 15: /* Verify Job */
1061 if (rc.verify_job_name) {
1062 ua->send_msg(_("Verify Job specified twice.\n"));
1065 rc.verify_job_name = ua->argv[i];
1068 case 16: /* files */
1069 rc.files = atoi(ua->argv[i]);
1073 case 17: /* catalog */
1074 rc.catalog_name = ua->argv[i];
1078 case 18: /* since */
1079 rc.since = ua->argv[i];
1083 case 19: /* cloned */
1088 case 20: /* write verify list output */
1089 rc.verify_list = ua->argv[i];
1092 case 21: /* Migration Job */
1093 if (rc.previous_job_name) {
1094 ua->send_msg(_("Migration Job specified twice.\n"));
1097 rc.previous_job_name = ua->argv[i];
1102 ua->send_msg(_("Pool specified twice.\n"));
1105 rc.pool_name = ua->argv[i];
1108 case 23: /* backupclient */
1109 if (rc.client_name) {
1110 ua->send_msg(_("Client specified twice.\n"));
1113 rc.client_name = ua->argv[i];
1116 case 24: /* restoreclient */
1117 if (rc.restore_client_name && !rc.mod) {
1118 ua->send_msg(_("Restore Client specified twice.\n"));
1121 rc.restore_client_name = ua->argv[i];
1127 } /* end strcase compare */
1128 } /* end keyword loop */
1130 * End of keyword for loop -- if not found, we got a bogus keyword
1133 Dmsg1(800, "%s not found\n", ua->argk[i]);
1135 * Special case for Job Name, it can be the first
1136 * keyword that has no value.
1138 if (!rc.job_name && !ua->argv[i]) {
1139 rc.job_name = ua->argk[i]; /* use keyword as job name */
1140 Dmsg1(800, "Set jobname=%s\n", rc.job_name);
1142 ua->send_msg(_("Invalid keyword: %s\n"), ua->argk[i]);
1146 } /* end argc loop */
1148 Dmsg0(800, "Done scan.\n");
1150 if (rc.catalog_name) {
1151 rc.catalog = GetCatalogResWithName(rc.catalog_name);
1152 if (rc.catalog == NULL) {
1153 ua->error_msg(_("Catalog \"%s\" not found\n"), rc.catalog_name);
1156 if (!acl_access_ok(ua, Catalog_ACL, rc.catalog->name())) {
1157 ua->error_msg(_("No authorization. Catalog \"%s\".\n"), rc.catalog->name());
1161 Dmsg1(800, "Using catalog=%s\n", NPRT(rc.catalog_name));
1165 rc.job = GetJobResWithName(rc.job_name);
1167 if (*rc.job_name != 0) {
1168 ua->send_msg(_("Job \"%s\" not found\n"), rc.job_name);
1170 rc.job = select_job_resource(ua);
1172 Dmsg1(800, "Found job=%s\n", rc.job_name);
1174 } else if (!rc.job) {
1175 ua->send_msg(_("A job name must be specified.\n"));
1176 rc.job = select_job_resource(ua);
1180 } else if (!acl_access_ok(ua, Job_ACL, rc.job->name())) {
1181 ua->error_msg( _("No authorization. Job \"%s\".\n"), rc.job->name());
1186 rc.pool = GetPoolResWithName(rc.pool_name);
1188 if (*rc.pool_name != 0) {
1189 ua->warning_msg(_("Pool \"%s\" not found.\n"), rc.pool_name);
1191 rc.pool = select_pool_resource(ua);
1193 } else if (!rc.pool) {
1194 rc.pool = rc.job->pool; /* use default */
1198 } else if (!acl_access_ok(ua, Pool_ACL, rc.pool->name())) {
1199 ua->error_msg(_("No authorization. Pool \"%s\".\n"), rc.pool->name());
1202 Dmsg1(100, "Using pool %s\n", rc.pool->name());
1204 if (rc.store_name) {
1205 rc.store->store = GetStoreResWithName(rc.store_name);
1206 pm_strcpy(rc.store->store_source, _("command line"));
1207 if (!rc.store->store) {
1208 if (*rc.store_name != 0) {
1209 ua->warning_msg(_("Storage \"%s\" not found.\n"), rc.store_name);
1211 rc.store->store = select_storage_resource(ua);
1212 pm_strcpy(rc.store->store_source, _("user selection"));
1214 } else if (!rc.store->store) {
1215 get_job_storage(rc.store, rc.job, NULL); /* use default */
1217 if (!rc.store->store) {
1218 ua->error_msg(_("No storage specified.\n"));
1220 } else if (!acl_access_ok(ua, Storage_ACL, rc.store->store->name())) {
1221 ua->error_msg(_("No authorization. Storage \"%s\".\n"),
1222 rc.store->store->name());
1225 Dmsg1(800, "Using storage=%s\n", rc.store->store->name());
1227 if (rc.client_name) {
1228 rc.client = GetClientResWithName(rc.client_name);
1230 if (*rc.client_name != 0) {
1231 ua->warning_msg(_("Client \"%s\" not found.\n"), rc.client_name);
1233 rc.client = select_client_resource(ua);
1235 } else if (!rc.client) {
1236 rc.client = rc.job->client; /* use default */
1240 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1241 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1245 Dmsg1(800, "Using client=%s\n", rc.client->name());
1247 if (rc.restore_client_name) {
1248 rc.client = GetClientResWithName(rc.restore_client_name);
1250 if (*rc.restore_client_name != 0) {
1251 ua->warning_msg(_("Restore Client \"%s\" not found.\n"), rc.restore_client_name);
1253 rc.client = select_client_resource(ua);
1255 } else if (!rc.client) {
1256 rc.client = rc.job->client; /* use default */
1260 } else if (!acl_access_ok(ua, Client_ACL, rc.client->name())) {
1261 ua->error_msg(_("No authorization. Client \"%s\".\n"),
1265 Dmsg1(800, "Using restore client=%s\n", rc.client->name());
1268 if (rc.fileset_name) {
1269 rc.fileset = GetFileSetResWithName(rc.fileset_name);
1271 ua->send_msg(_("FileSet \"%s\" not found.\n"), rc.fileset_name);
1272 rc.fileset = select_fileset_resource(ua);
1274 } else if (!rc.fileset) {
1275 rc.fileset = rc.job->fileset; /* use default */
1279 } else if (!acl_access_ok(ua, FileSet_ACL, rc.fileset->name())) {
1280 ua->send_msg(_("No authorization. FileSet \"%s\".\n"),
1281 rc.fileset->name());
1285 if (rc.verify_job_name) {
1286 rc.verify_job = GetJobResWithName(rc.verify_job_name);
1287 if (!rc.verify_job) {
1288 ua->send_msg(_("Verify Job \"%s\" not found.\n"), rc.verify_job_name);
1289 rc.verify_job = select_job_resource(ua);
1291 } else if (!rc.verify_job) {
1292 rc.verify_job = rc.job->verify_job;
1295 if (rc.previous_job_name) {
1296 rc.previous_job = GetJobResWithName(rc.previous_job_name);
1297 if (!rc.previous_job) {
1298 ua->send_msg(_("Migration Job \"%s\" not found.\n"), rc.previous_job_name);
1299 rc.previous_job = select_job_resource(ua);
1302 rc.previous_job = rc.job->verify_job;