]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_run.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / dird / ua_run.c
1 /*
2  *
3  *   Bacula Director -- Run Command
4  *
5  *     Kern Sibbald, December MMI
6  */
7
8 /*
9    Copyright (C) 2001, 2002 Kern Sibbald and John Walker
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2 of
14    the License, or (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public
22    License along with this program; if not, write to the Free
23    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
24    MA 02111-1307, USA.
25
26  */
27
28 #include "bacula.h"
29 #include "dird.h"
30 #include "ua.h"
31
32 /* Imported subroutines */
33 extern void run_job(JCR *jcr);
34
35 /* Imported variables */
36 extern struct s_jl joblevels[];
37
38 /*
39  * For Backup and Verify Jobs
40  *     run [job=]<job-name> level=<level-name>
41  *
42  * For Restore Jobs
43  *     run <job-name> jobid=nn
44  *
45  */
46 int runcmd(UAContext *ua, char *cmd)
47 {
48    JOB *job;
49    JCR *jcr;
50    char *job_name, *level_name, *jid, *store_name;
51    char *where, *fileset_name, *client_name;
52    int i, j, found;
53    STORE *store;
54    CLIENT *client;
55    FILESET *fileset;
56    static char *kw[] = {
57       N_("job"),
58       N_("jobid"),
59       N_("client"),
60       N_("fileset"),
61       N_("level"),
62       N_("storage"),
63       N_("where"),
64       NULL};
65
66    if (!open_db(ua)) {
67       return 1;
68    }
69
70    job_name = NULL;
71    level_name = NULL;
72    jid = NULL;
73    store_name = NULL;
74    where = NULL;
75    client_name = NULL;
76    fileset_name = NULL;
77
78    Dmsg1(20, "run: %s\n", ua->UA_sock->msg);
79
80    for (i=1; i<ua->argc; i++) {
81       found = False;
82       Dmsg2(200, "Doing arg %d = %s\n", i, ua->argk[i]);
83       for (j=0; kw[j]; j++) {
84          if (strcasecmp(ua->argk[i], _(kw[j])) == 0) {
85             if (!ua->argv[i]) {
86                bsendmsg(ua, _("Value missing for keyword %s\n"), ua->argk[i]);
87                return 1;
88             }
89             Dmsg1(200, "Got keyword=%s\n", kw[j]);
90             switch (j) {
91                case 0: /* job */
92                   if (job_name) {
93                      bsendmsg(ua, _("Job name specified twice.\n"));
94                      return 1;
95                   }
96                   job_name = ua->argv[i];
97                   found = True;
98                   break;
99                case 1: /* JobId */
100                   if (jid) {
101                      bsendmsg(ua, _("JobId specified twice.\n"));
102                      return 1;
103                   }
104                   jid = ua->argv[i];
105                   found = True;
106                   break;
107                case 2: /* client */
108                   if (client_name) {
109                      bsendmsg(ua, _("Client specified twice.\n"));
110                      return 1;
111                   }
112                   client_name = ua->argv[i];
113                   found = True;
114                   break;
115                case 3: /* fileset */
116                   if (fileset_name) {
117                      bsendmsg(ua, _("FileSet specified twice.\n"));
118                      return 1;
119                   }
120                   fileset_name = ua->argv[i];
121                   found = True;
122                   break;
123                case 4: /* level */
124                   if (level_name) {
125                      bsendmsg(ua, _("Level specified twice.\n"));
126                      return 1;
127                   }
128                   level_name = ua->argv[i];
129                   found = True;
130                   break;
131                case 5: /* storage */
132                   if (store_name) {
133                      bsendmsg(ua, _("Storage specified twice.\n"));
134                      return 1;
135                   }
136                   store_name = ua->argv[i];
137                   found = True;
138                   break;
139                case 6: /* where */
140                   if (where) {
141                      bsendmsg(ua, _("Where specified twice.\n"));
142                      return 1;
143                   }
144                   where = ua->argv[i];
145                   break;
146                   found = True;
147                default:
148                   break;
149             }
150          }
151       } /* end keyword loop */
152       if (!found) {
153          Dmsg1(200, "%s not found\n", ua->argk[i]);
154          /*
155           * Special case for Job Name, it can be the first
156           * keyword that has no value.
157           */
158          if (!job_name && !ua->argv[i]) {
159             job_name = ua->argk[i];   /* use keyword as job name */
160             Dmsg1(200, "Set jobname=%s\n", job_name);
161          } else {
162             bsendmsg(ua, _("Invalid keyword %s\n"), ua->argk[i]);
163             return 1;
164          }
165       }
166    } /* end argc loop */
167              
168    Dmsg0(20, "Done scan.\n");
169    if (job_name) {
170       /* Find Job */
171       job = (JOB *)GetResWithName(R_JOB, job_name);
172       if (!job) {
173          bsendmsg(ua, _("Job %s: not found\n"), job_name);
174          job = select_job_resource(ua);
175       } else {
176          Dmsg1(20, "Found job=%s\n", job_name);
177       }
178    } else {
179       bsendmsg(ua, _("A job name must be specified.\n"));
180       job = select_job_resource(ua);
181    }
182    if (!job) {
183       return 1;
184    }
185
186    if (store_name) {
187       store = (STORE *)GetResWithName(R_STORAGE, store_name);
188       if (!store) {
189          bsendmsg(ua, _("Storage %s not found.\n"), store_name);
190          store = select_storage_resource(ua);
191       }
192    } else {
193       store = job->storage;           /* use default */
194    }
195    if (!store) {
196       return 1;
197    }
198
199    jcr = new_jcr(sizeof(JCR), dird_free_jcr);
200    set_jcr_defaults(jcr, job);
201    jcr->store = store;                /* set possible new Storage */
202
203 try_again:
204    Dmsg1(20, "JobType=%c\n", jcr->JobType);
205    switch (jcr->JobType) {
206       case JT_BACKUP:
207       case JT_VERIFY:
208          if (level_name) {
209             /* Look up level name and pull code */
210             lcase(level_name);
211             found = 0;
212             for (i=0; joblevels[i].level_name; i++) {
213                if (strcasecmp(level_name, _(joblevels[i].level_name)) == 0) {
214                   jcr->level = joblevels[i].level;
215                   found = 1;
216                   break;
217                }
218             }
219             if (!found) { 
220                bsendmsg(ua, _("Level %s not valid.\n"), level_name);
221                free_jcr(jcr);
222                return 1;
223             }
224          }
225          level_name = NULL;
226          bsendmsg(ua, _("Run %s job\n\
227 JobName:  %s\n\
228 FileSet:  %s\n\
229 Level:    %s\n\
230 Client:   %s\n\
231 Storage:  %s\n"),
232                  jcr->JobType==JT_BACKUP?_("Backup"):_("Verify"),
233                  job->hdr.name,
234                  jcr->fileset->hdr.name,
235                  level_to_str(jcr->level),
236                  jcr->client->hdr.name,
237                  jcr->store->hdr.name);
238          break;
239       case JT_RESTORE:
240          if (jcr->RestoreJobId == 0) {
241             if (jid) {
242                jcr->RestoreJobId = atoi(jid);
243             } else {
244                if (!get_cmd(ua, _("Please enter a JobId for restore: "))) {
245                   free_jcr(jcr);
246                   return 1;
247                }  
248                jcr->RestoreJobId = atoi(ua->cmd);
249             }
250          }
251          jcr->level = 'F';            /* ***FIXME*** */
252          Dmsg1(20, "JobId to restore=%d\n", jcr->RestoreJobId);
253          bsendmsg(ua, _("Run Restore job\n\
254 JobName:    %s\n\
255 Where:      %s\n\
256 RestoreId:  %d\n\
257 Level:      %s\n\
258 FileSet:    %s\n\
259 Client:     %s\n\
260 Storage:    %s\n"),
261                  job->hdr.name,
262                  jcr->RestoreWhere?jcr->RestoreWhere:job->RestoreWhere,
263                  jcr->RestoreJobId,
264                  level_to_str(jcr->level),
265                  jcr->fileset->hdr.name,
266                  jcr->client->hdr.name,
267                  jcr->store->hdr.name);
268          break;
269       default:
270          bsendmsg(ua, _("Unknown Job Type=%d\n"), jcr->JobType);
271          free_jcr(jcr);
272          return 1;
273    }
274    if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
275       free_jcr(jcr);
276       return 1;
277    }
278    if (strcasecmp(ua->cmd, _("mod")) == 0) {
279       start_prompt(ua, _("Parameters to modify:\n"));
280       add_prompt(ua, _("Job"));
281       add_prompt(ua, _("Level"));
282       add_prompt(ua, _("FileSet"));
283       add_prompt(ua, _("Client"));
284       add_prompt(ua, _("Storage"));
285       if (jcr->JobType == JT_RESTORE) {
286          add_prompt(ua, _("Where"));
287          add_prompt(ua, _("JobId"));
288       }
289       switch (do_prompt(ua, _("Select parameter to modify"), NULL)) {
290       case 0:
291          /* Job */
292          job = select_job_resource(ua);
293          if (job) {
294             jcr->job = job;
295             set_jcr_defaults(jcr, job);
296             goto try_again;
297          }
298          break;
299       case 1:
300          /* Level */
301          if (jcr->JobType == JT_BACKUP) {
302             start_prompt(ua, _("Levels:\n"));
303             add_prompt(ua, _("Full"));
304             add_prompt(ua, _("Incremental"));
305             add_prompt(ua, _("Differential"));
306             add_prompt(ua, _("Level"));
307             add_prompt(ua, _("Since"));
308             switch (do_prompt(ua, _("Select level"), NULL)) {
309             case 0:
310                jcr->level = L_FULL;
311                break;
312             case 1:
313                jcr->level = L_INCREMENTAL;
314                break;
315             case 2:
316                jcr->level = L_DIFFERENTIAL;
317                break;
318             case 3:
319                jcr->level = L_LEVEL;
320                break;
321             case 4:
322                jcr->level = L_SINCE;
323                break;
324             default:
325                break;
326             }
327             goto try_again;
328          } else if (jcr->JobType == JT_VERIFY) {
329             start_prompt(ua, _("Levels:\n"));
330             add_prompt(ua, _("Initialize Catalog"));
331             add_prompt(ua, _("Verify from Catalog"));
332             add_prompt(ua, _("Verify Volume"));
333             add_prompt(ua, _("Verify Volume Data"));
334             switch (do_prompt(ua, _("Select level"), NULL)) {
335             case 0:
336                jcr->level = L_VERIFY_INIT;
337                break;
338             case 1:
339                jcr->level = L_VERIFY_CATALOG;
340                break;
341             case 2:
342                jcr->level = L_VERIFY_VOLUME;
343                break;
344             case 3:
345                jcr->level = L_VERIFY_DATA;
346                break;
347             default:
348                break;
349             }
350             goto try_again;
351          }
352          goto try_again;
353       case 2:
354          /* FileSet */
355          fileset = select_fs_resource(ua);
356          if (fileset) {
357             jcr->fileset = fileset;
358             goto try_again;
359          }      
360          break;
361       case 3:
362          client = select_client_resource(ua);
363          if (client) {
364             jcr->client = client;
365             goto try_again;
366          }
367          break;
368       case 4:
369          store = select_storage_resource(ua);
370          if (store) {
371             jcr->store = store;
372             goto try_again;
373          }
374          break;
375       case 5:
376          /* Where */
377          if (!get_cmd(ua, _("Please enter path prefix (where) for restore: "))) {
378             break;
379          }
380          if (ua->cmd[0] != '/') {
381             bsendmsg(ua, _("Prefix must begin with a /\n"));
382          } else {
383             if (jcr->RestoreWhere) {
384                free(jcr->RestoreWhere);
385             }
386             jcr->RestoreWhere = bstrdup(ua->cmd);
387          }  
388          goto try_again;
389       case 6:
390          /* JobId */
391          jid = NULL;                  /* force reprompt */
392          jcr->RestoreJobId = 0;
393          goto try_again;
394       default: 
395          goto try_again;
396       }
397       bsendmsg(ua, _("Job not run.\n"));
398       free_jcr(jcr);
399       return 1;
400    }
401    if (strcasecmp(ua->cmd, _("yes")) != 0) {
402       bsendmsg(ua, _("Job not run.\n"));
403       free_jcr(jcr);
404       return 1;
405    }
406
407    Dmsg1(200, "Calling run_job job=%x\n", jcr->job);
408    run_job(jcr);
409    return 1;
410 }