3 * Bacula Director -- Run Command
5 * Kern Sibbald, December MMI
11 Copyright (C) 2001, 2002 Kern Sibbald and John Walker
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of
16 the License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public
24 License along with this program; if not, write to the Free
25 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
34 /* Imported subroutines */
35 extern void run_job(JCR *jcr);
37 /* Imported variables */
38 extern struct s_jl joblevels[];
41 * For Backup and Verify Jobs
42 * run [job=]<job-name> level=<level-name>
45 * run <job-name> jobid=nn
48 int runcmd(UAContext *ua, char *cmd)
51 char *job_name, *level_name, *jid, *store_name;
52 char *where, *fileset_name, *client_name, *bootstrap;
56 CLIENT *client = NULL;
57 FILESET *fileset = NULL;
82 Dmsg1(000, "run: %s\n", ua->UA_sock->msg);
84 for (i=1; i<ua->argc; i++) {
86 Dmsg2(200, "Doing arg %d = %s\n", i, ua->argk[i]);
87 for (j=0; !found && kw[j]; j++) {
88 if (strcasecmp(ua->argk[i], _(kw[j])) == 0) {
90 bsendmsg(ua, _("Value missing for keyword %s\n"), ua->argk[i]);
93 Dmsg1(200, "Got keyword=%s\n", kw[j]);
97 bsendmsg(ua, _("Job name specified twice.\n"));
100 job_name = ua->argv[i];
105 bsendmsg(ua, _("JobId specified twice.\n"));
113 bsendmsg(ua, _("Client specified twice.\n"));
116 client_name = ua->argv[i];
119 case 3: /* fileset */
121 bsendmsg(ua, _("FileSet specified twice.\n"));
124 fileset_name = ua->argv[i];
129 bsendmsg(ua, _("Level specified twice.\n"));
132 level_name = ua->argv[i];
135 case 5: /* storage */
137 bsendmsg(ua, _("Storage specified twice.\n"));
140 store_name = ua->argv[i];
145 bsendmsg(ua, _("Where specified twice.\n"));
151 case 7: /* bootstrap */
153 bsendmsg(ua, _("Bootstrap specified twice.\n"));
156 bootstrap = ua->argv[i];
162 } /* end strcase compare */
163 } /* end keyword loop */
165 Dmsg1(200, "%s not found\n", ua->argk[i]);
167 * Special case for Job Name, it can be the first
168 * keyword that has no value.
170 if (!job_name && !ua->argv[i]) {
171 job_name = ua->argk[i]; /* use keyword as job name */
172 Dmsg1(200, "Set jobname=%s\n", job_name);
174 bsendmsg(ua, _("Invalid keyword: %s\n"), ua->argk[i]);
178 } /* end argc loop */
180 Dmsg0(200, "Done scan.\n");
186 job = (JOB *)GetResWithName(R_JOB, job_name);
188 bsendmsg(ua, _("Job %s: not found\n"), job_name);
189 job = select_job_resource(ua);
191 Dmsg1(200, "Found job=%s\n", job_name);
194 bsendmsg(ua, _("A job name must be specified.\n"));
195 job = select_job_resource(ua);
202 store = (STORE *)GetResWithName(R_STORAGE, store_name);
204 bsendmsg(ua, _("Storage %s not found.\n"), store_name);
205 store = select_storage_resource(ua);
208 store = job->storage; /* use default */
215 client = (CLIENT *)GetResWithName(R_CLIENT, client_name);
217 bsendmsg(ua, _("Client %s not found.\n"), client_name);
218 client = select_client_resource(ua);
221 client = job->client; /* use default */
228 fileset = (FILESET *)GetResWithName(R_FILESET, fileset_name);
230 bsendmsg(ua, _("FileSet %s not found.\n"), fileset_name);
231 fileset = select_fileset_resource(ua);
234 fileset = job->fileset; /* use default */
241 /* Create JCR to run job */
242 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
243 set_jcr_defaults(jcr, job);
244 init_msg(jcr, jcr->msgs); /* start message handler */
247 jcr->client = client;
248 jcr->fileset = fileset;
250 if (jcr->RestoreWhere) {
251 free(jcr->RestoreWhere);
253 jcr->RestoreWhere = bstrdup(where);
256 if (jcr->RestoreBootstrap) {
257 free(jcr->RestoreBootstrap);
259 jcr->RestoreBootstrap = bstrdup(bootstrap);
266 Dmsg1(20, "JobType=%c\n", jcr->JobType);
267 switch (jcr->JobType) {
270 bsendmsg(ua, _("Run %s job\n\
277 jcr->fileset->hdr.name,
278 NPRT(jcr->client->hdr.name),
279 NPRT(jcr->store->hdr.name));
285 /* Look up level name and pull code */
287 for (i=0; joblevels[i].level_name; i++) {
288 if (strcasecmp(level_name, _(joblevels[i].level_name)) == 0) {
289 jcr->JobLevel = joblevels[i].level;
295 bsendmsg(ua, _("Level %s not valid.\n"), level_name);
301 bsendmsg(ua, _("Run %s job\n\
307 jcr->JobType==JT_BACKUP?_("Backup"):_("Verify"),
309 jcr->fileset->hdr.name,
310 level_to_str(jcr->JobLevel),
311 jcr->client->hdr.name,
312 jcr->store->hdr.name);
315 if (jcr->RestoreJobId == 0 && !jcr->RestoreBootstrap) {
317 jcr->RestoreJobId = atoi(jid);
319 if (!get_cmd(ua, _("Please enter a JobId for restore: "))) {
323 jcr->RestoreJobId = atoi(ua->cmd);
326 jcr->JobLevel = 'F'; /* default level */
327 Dmsg1(20, "JobId to restore=%d\n", jcr->RestoreJobId);
328 bsendmsg(ua, _("Run Restore job\n\
337 NPRT(jcr->RestoreBootstrap),
338 jcr->RestoreWhere?jcr->RestoreWhere:NPRT(job->RestoreWhere),
339 jcr->fileset->hdr.name,
340 jcr->client->hdr.name,
341 jcr->store->hdr.name,
342 jcr->RestoreJobId==0?"*None*":edit_uint64(jcr->RestoreJobId, ec1));
345 bsendmsg(ua, _("Unknown Job Type=%d\n"), jcr->JobType);
349 if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
351 return 0; /* do not run */
354 * At user request modify parameters of job to be run.
356 if (strcasecmp(ua->cmd, _("mod")) == 0) {
359 start_prompt(ua, _("Parameters to modify:\n"));
360 add_prompt(ua, _("Level")); /* 0 */
361 add_prompt(ua, _("Storage")); /* 1 */
362 add_prompt(ua, _("Job")); /* 2 */
363 add_prompt(ua, _("FileSet")); /* 3 */
364 add_prompt(ua, _("Client")); /* 4 */
365 if (jcr->JobType == JT_RESTORE) {
366 add_prompt(ua, _("Bootstrap")); /* 5 */
367 add_prompt(ua, _("Where")); /* 6 */
368 add_prompt(ua, _("JobId")); /* 7 */
370 switch (do_prompt(ua, _("Select parameter to modify"), NULL)) {
373 if (jcr->JobType == JT_BACKUP) {
374 start_prompt(ua, _("Levels:\n"));
375 add_prompt(ua, _("Full"));
376 add_prompt(ua, _("Incremental"));
377 add_prompt(ua, _("Differential"));
378 add_prompt(ua, _("Level"));
379 add_prompt(ua, _("Since"));
380 switch (do_prompt(ua, _("Select level"), NULL)) {
382 jcr->JobLevel = L_FULL;
385 jcr->JobLevel = L_INCREMENTAL;
388 jcr->JobLevel = L_DIFFERENTIAL;
391 jcr->JobLevel = L_LEVEL;
394 jcr->JobLevel = L_SINCE;
400 } else if (jcr->JobType == JT_VERIFY) {
401 start_prompt(ua, _("Levels:\n"));
402 add_prompt(ua, _("Initialize Catalog"));
403 add_prompt(ua, _("Verify Catalog"));
404 add_prompt(ua, _("Verify Volume"));
405 add_prompt(ua, _("Verify Volume Data"));
406 switch (do_prompt(ua, _("Select level"), NULL)) {
408 jcr->JobLevel = L_VERIFY_INIT;
411 jcr->JobLevel = L_VERIFY_CATALOG;
414 jcr->JobLevel = L_VERIFY_VOLUME_TO_CATALOG;
417 jcr->JobLevel = L_VERIFY_DATA;
424 bsendmsg(ua, _("Level not appropriate for this Job. Cannot be changed.\n"));
428 store = select_storage_resource(ua);
436 job = select_job_resource(ua);
439 set_jcr_defaults(jcr, job);
445 fileset = select_fileset_resource(ua);
447 jcr->fileset = fileset;
452 client = select_client_resource(ua);
454 jcr->client = client;
460 if (!get_cmd(ua, _("Please enter the Bootstrap file name: "))) {
463 if (jcr->RestoreBootstrap) {
464 free(jcr->RestoreBootstrap);
465 jcr->RestoreBootstrap = NULL;
467 if (ua->cmd[0] != 0) {
468 jcr->RestoreBootstrap = bstrdup(ua->cmd);
469 fd = fopen(jcr->RestoreBootstrap, "r");
471 bsendmsg(ua, _("Warning cannot open %s: ERR=%s\n"),
472 jcr->RestoreBootstrap, strerror(errno));
473 free(jcr->RestoreBootstrap);
474 jcr->RestoreBootstrap = NULL;
482 if (!get_cmd(ua, _("Please enter path prefix (where) for restore: "))) {
485 /* ***FIXME*** allow drive:/ for Windows */
486 if (ua->cmd[0] != '/') {
487 bsendmsg(ua, _("Prefix must begin with a /\n"));
489 if (jcr->RestoreWhere) {
490 free(jcr->RestoreWhere);
492 jcr->RestoreWhere = bstrdup(ua->cmd);
497 jid = NULL; /* force reprompt */
498 jcr->RestoreJobId = 0;
499 if (jcr->RestoreBootstrap) {
500 bsendmsg(ua, _("You must set the bootstrap file to NULL to be able to specify a JobId.\n"));
506 bsendmsg(ua, _("Job not run.\n"));
508 return 0; /* error do no run Job */
510 if (strcasecmp(ua->cmd, _("yes")) != 0) {
511 bsendmsg(ua, _("Job not run.\n"));
513 return 0; /* do not run */
516 Dmsg1(200, "Calling run_job job=%x\n", jcr->job);