]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/parse_bsr.c
0a32e9cdc825c5adf9fa01408a06d3c3c59390ab
[bacula/bacula] / bacula / src / stored / parse_bsr.c
1 /*     
2  *   Parse a Bootstrap Records (used for restores) 
3  *  
4  *     Kern Sibbald, June MMII
5  *
6  *   Version $Id$
7  */
8
9 /*
10    Copyright (C) 2002 Kern Sibbald and John Walker
11
12    This program is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public License as
14    published by the Free Software Foundation; either version 2 of
15    the License, or (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20    General Public License for more details.
21
22    You should have received a copy of the GNU General Public
23    License along with this program; if not, write to the Free
24    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25    MA 02111-1307, USA.
26
27  */
28
29
30 #include "bacula.h"
31 #include "stored.h"
32
33 typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr);
34
35 static BSR *store_vol(LEX *lc, BSR *bsr);
36 static BSR *store_client(LEX *lc, BSR *bsr);
37 static BSR *store_job(LEX *lc, BSR *bsr);
38 static BSR *store_jobid(LEX *lc, BSR *bsr);
39 static BSR *store_jobtype(LEX *lc, BSR *bsr);
40 static BSR *store_joblevel(LEX *lc, BSR *bsr);
41 static BSR *store_file_index(LEX *lc, BSR *bsr);
42 static BSR *store_sessid(LEX *lc, BSR *bsr);
43 static BSR *store_volfile(LEX *lc, BSR *bsr);
44 static BSR *store_sesstime(LEX *lc, BSR *bsr);
45 static BSR *store_include(LEX *lc, BSR *bsr);
46 static BSR *store_exclude(LEX *lc, BSR *bsr);
47
48 struct kw_items {
49    char *name;
50    ITEM_HANDLER *handler;
51 };
52
53 struct kw_items items[] = {
54    {"volume", store_vol},
55    {"client", store_client},
56    {"job", store_job},
57    {"jobid", store_jobid},
58    {"fileindex", store_file_index},
59    {"jobtype", store_jobtype},
60    {"joblevel", store_joblevel},
61    {"volsessionid", store_sessid},
62    {"volsessiontime", store_sesstime},
63    {"include", store_include},
64    {"exclude", store_exclude},
65    {"volfile", store_volfile},
66    {NULL, NULL}
67
68 };
69
70 static BSR *new_bsr() 
71 {
72    BSR *bsr = (BSR *)malloc(sizeof(BSR));
73    memset(bsr, 0, sizeof(BSR));
74    return bsr;
75 }
76
77 /*********************************************************************
78  *
79  *      Parse Bootstrap file
80  *
81  */
82 BSR *parse_bsr(char *cf)
83 {
84    LEX *lc = NULL;
85    int token, i;
86    BSR *root_bsr = new_bsr();
87    BSR *bsr = root_bsr;
88
89    Dmsg0(200, "Enter parse_bsf()\n");
90    lc = lex_open_file(lc, cf);
91    while ((token=lex_get_token(lc)) != T_EOF) {
92       Dmsg1(150, "parse got token=%s\n", lex_tok_to_str(token));
93       if (token == T_EOL) {
94          continue;
95       }
96       if (token != T_IDENTIFIER) {
97          scan_err1(lc, "Expected a keyword identifier, got: %s", lc->str);
98       }
99       for (i=0; items[i].name; i++) {
100          if (strcasecmp(items[i].name, lc->str) == 0) {
101             token = lex_get_token(lc);
102             Dmsg1 (150, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
103             if (token != T_EQUALS) {
104                scan_err1(lc, "expected an equals, got: %s", lc->str);
105             }
106             Dmsg1(100, "calling handler for %s\n", items[i].name);
107             /* Call item handler */
108             bsr = items[i].handler(lc, bsr);
109             i = -1;
110             break;
111          }
112       }
113       if (i >= 0) {
114          Dmsg1(150, "Keyword = %s\n", lc->str);
115          scan_err1(lc, "Keyword %s not found", lc->str);
116       }
117
118    }
119    lc = lex_close_file(lc);
120    Dmsg0(200, "Leave parse_bsf()\n");
121    return root_bsr;
122 }
123
124 static BSR *store_vol(LEX *lc, BSR *bsr)
125 {
126    int token;
127     
128    token = lex_get_token(lc);
129    if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
130       scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
131    } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
132       scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
133          lc->str_len, MAX_RES_NAME_LENGTH);
134    } else {
135       if (bsr->VolumeName) {
136          bsr->next = new_bsr();
137          bsr = bsr->next;
138       }
139       bsr->VolumeName = bstrdup(lc->str);
140    }
141    scan_to_eol(lc);
142    return bsr;
143 }
144
145 static BSR *store_client(LEX *lc, BSR *bsr)
146 {
147    int token;
148    BSR_CLIENT *client;
149     
150    for (;;) {
151       lc->expect = T_NAME;
152       token = lex_get_token(lc);
153       client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT));
154       memset(client, 0, sizeof(BSR_CLIENT));
155       client->ClientName = bstrdup(lc->str);
156       /* Add it to the end of the client chain */
157       if (!bsr->client) {
158          bsr->client = client;
159       } else {
160          BSR_CLIENT *bc = bsr->client;
161          for ( ;; ) {
162             if (bc->next) {
163                bc = bc->next;
164             } else {
165                bc->next = client;
166                break;
167             }
168          }
169       }
170       lc->expect = 0;
171       token = lex_get_token(lc);
172       if (token != T_COMMA) {
173          break;
174       }
175    }
176 // scan_to_eol(lc);
177    return bsr;
178 }
179
180 static BSR *store_job(LEX *lc, BSR *bsr)
181 {
182    int token;
183    BSR_JOB *job;
184     
185    lc->expect = T_NAME;
186    token = lex_get_token(lc);
187    job = (BSR_JOB *)malloc(sizeof(BSR_JOB));
188    memset(job, 0, sizeof(BSR_JOB));
189    job->Job = bstrdup(lc->str);
190    /* Add it to the end of the client chain */
191    if (!bsr->job) {
192       bsr->job = job;
193    } else {
194       /* Add to end of chain */
195       BSR_JOB *bc = bsr->job;
196       for ( ;bc->next; bc=bc->next)
197          { }
198       bc->next = job;
199    }
200    scan_to_eol(lc);
201    return bsr;
202 }
203
204 static BSR *store_file_index(LEX *lc, BSR *bsr)
205 {
206    int token;
207    BSR_FINDEX *findex;
208
209    for (;;) {
210       lc->expect = T_PINT32_RANGE;
211       token = lex_get_token(lc);
212       findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX));
213       memset(findex, 0, sizeof(BSR_FINDEX));
214       findex->findex = lc->pint32_val;
215       findex->findex2 = lc->pint32_val2;
216       /* Add it to the end of the chain */
217       if (!bsr->FileIndex) {
218          bsr->FileIndex = findex;
219       } else {
220          /* Add to end of chain */
221          BSR_FINDEX *bs = bsr->FileIndex;
222          for ( ;bs->next; bs=bs->next)
223            {  }
224          bs->next = findex;
225       }
226       lc->expect = 0;
227       token = lex_get_token(lc);
228       if (token != T_COMMA) {
229          break;
230       }
231    }
232 // scan_to_eol(lc);
233    return bsr;
234 }
235
236
237 static BSR *store_jobid(LEX *lc, BSR *bsr)
238 {
239    int token;
240    BSR_JOBID *jobid;
241
242    for (;;) {
243       lc->expect = T_PINT32_RANGE;
244       token = lex_get_token(lc);
245       jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID));
246       memset(jobid, 0, sizeof(BSR_JOBID));
247       jobid->JobId = lc->pint32_val;
248       jobid->JobId2 = lc->pint32_val2;
249       /* Add it to the end of the chain */
250       if (!bsr->JobId) {
251          bsr->JobId = jobid;
252       } else {
253          /* Add to end of chain */
254          BSR_JOBID *bs = bsr->JobId;
255          for ( ;bs->next; bs=bs->next)
256            {  }
257          bs->next = jobid;
258       }
259       lc->expect = 0;
260       token = lex_get_token(lc);
261       if (token != T_COMMA) {
262          break;
263       }
264    }
265 // scan_to_eol(lc);
266    return bsr;
267 }
268
269 static BSR *store_jobtype(LEX *lc, BSR *bsr)
270 {
271    /* *****FIXME****** */
272    Dmsg0(-1, "JobType not yet implemented\n");
273    return bsr;
274 }
275
276
277 static BSR *store_joblevel(LEX *lc, BSR *bsr)
278 {
279    /* *****FIXME****** */
280    Dmsg0(-1, "JobLevel not yet implemented\n");
281    return bsr;
282 }
283
284
285
286
287 /*
288  * Routine to handle Volume start/end file   
289  */
290 static BSR *store_volfile(LEX *lc, BSR *bsr)
291 {
292    int token;
293    BSR_VOLFILE *volfile;
294
295    for (;;) {
296       lc->expect = T_PINT32_RANGE;
297       token = lex_get_token(lc);
298       volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE));
299       memset(volfile, 0, sizeof(BSR_VOLFILE));
300       volfile->sfile = lc->pint32_val;
301       volfile->efile = lc->pint32_val2;
302       /* Add it to the end of the chain */
303       if (!bsr->volfile) {
304          bsr->volfile = volfile;
305       } else {
306          /* Add to end of chain */
307          BSR_VOLFILE *bs = bsr->volfile;
308          for ( ;bs->next; bs=bs->next)
309            {  }
310          bs->next = volfile;
311       }
312       lc->expect = 0;
313       token = lex_get_token(lc);
314       if (token != T_COMMA) {
315          break;
316       }
317    }
318 // scan_to_eol(lc);
319    return bsr;
320 }
321
322
323
324 static BSR *store_sessid(LEX *lc, BSR *bsr)
325 {
326    int token;
327    BSR_SESSID *sid;
328
329    for (;;) {
330       lc->expect = T_PINT32_RANGE;
331       token = lex_get_token(lc);
332       sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID));
333       memset(sid, 0, sizeof(BSR_SESSID));
334       sid->sessid = lc->pint32_val;
335       sid->sessid2 = lc->pint32_val2;
336       /* Add it to the end of the chain */
337       if (!bsr->sessid) {
338          bsr->sessid = sid;
339       } else {
340          /* Add to end of chain */
341          BSR_SESSID *bs = bsr->sessid;
342          for ( ;bs->next; bs=bs->next)
343            {  }
344          bs->next = sid;
345       }
346       lc->expect = 0;
347       token = lex_get_token(lc);
348       if (token != T_COMMA) {
349          break;
350       }
351    }
352 // scan_to_eol(lc);
353    return bsr;
354 }
355
356 static BSR *store_sesstime(LEX *lc, BSR *bsr)
357 {
358    int token;
359    BSR_SESSTIME *stime;
360
361    lc->expect = T_PINT32;
362    token = lex_get_token(lc);
363    stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME));
364    memset(stime, 0, sizeof(BSR_SESSTIME));
365    stime->sesstime = lc->pint32_val;
366    /* Add it to the end of the chain */
367    if (!bsr->sesstime) {
368       bsr->sesstime = stime;
369    } else {
370       /* Add to end of chain */
371       BSR_SESSTIME *bs = bsr->sesstime;
372       for ( ;bs->next; bs=bs->next)
373          { }
374       bs->next = stime;
375    }
376    scan_to_eol(lc);
377    return bsr;
378 }
379
380 static BSR *store_include(LEX *lc, BSR *bsr)
381 {
382    scan_to_eol(lc);
383    return bsr;
384 }
385
386 static BSR *store_exclude(LEX *lc, BSR *bsr)
387 {
388    scan_to_eol(lc);
389    return bsr;
390 }
391
392 void dump_volfile(BSR_VOLFILE *volfile)
393 {
394    if (!volfile) {
395       return;
396    }
397    Dmsg2(-1,
398 "VolFile     : %u-%u\n", volfile->sfile, volfile->efile);
399    dump_volfile(volfile->next);
400 }
401
402 void dump_findex(BSR_FINDEX *FileIndex)
403 {
404    if (!FileIndex) {
405       return;
406    }
407    if (FileIndex->findex == FileIndex->findex2) {
408       Dmsg1(-1, "FileIndex   : %u\n", FileIndex->findex);
409    } else {
410       Dmsg2(-1, "FileIndex   : %u-%u\n", FileIndex->findex, FileIndex->findex2);
411    }
412    dump_findex(FileIndex->next);
413 }
414
415 void dump_jobid(BSR_JOBID *jobid)
416 {
417    if (!jobid) {
418       return;
419    }
420    if (jobid->JobId == jobid->JobId2) {
421       Dmsg1(-1, "JobId       : %u\n", jobid->JobId);
422    } else {
423       Dmsg2(-1, "JobId       : %u-%u\n", jobid->JobId, jobid->JobId2);
424    }
425    dump_jobid(jobid->next);
426 }
427
428 void dump_sessid(BSR_SESSID *sessid)
429 {
430    if (!sessid) {
431       return;
432    }
433    if (sessid->sessid == sessid->sessid2) {
434       Dmsg1(-1, "SessId      : %u\n", sessid->sessid);
435    } else {
436       Dmsg2(-1, "SessId      : %u-%u\n", sessid->sessid, sessid->sessid2);
437    }
438    dump_sessid(sessid->next);
439 }
440
441
442 void dump_client(BSR_CLIENT *client)
443 {
444    if (!client) {
445       return;
446    }
447    Dmsg1(-1, "Client      : %s\n", client->ClientName);
448    dump_client(client->next);
449 }
450
451 void dump_job(BSR_JOB *job)
452 {
453    if (!job) {
454       return;
455    }
456    Dmsg1(-1, "Job          : %s\n", job->Job);
457    dump_job(job->next);
458 }
459
460 void dump_sesstime(BSR_SESSTIME *sesstime)
461 {
462    if (!sesstime) {
463       return;
464    }
465    Dmsg1(-1, "SessTime    : %u\n", sesstime->sesstime);
466    dump_sesstime(sesstime->next);
467 }
468
469
470
471
472
473 void dump_bsr(BSR *bsr)
474 {
475    if (!bsr) {
476       Dmsg0(-1, "BSR is NULL\n");
477       return;
478    }
479    Dmsg2(-1,   
480 "Next        : 0x%x\n"
481 "VolumeName  : %s\n",
482                  bsr->next,
483                  bsr->VolumeName ? bsr->VolumeName : "*None*");
484    dump_sessid(bsr->sessid);
485    dump_sesstime(bsr->sesstime);
486    dump_volfile(bsr->volfile);
487    dump_client(bsr->client);
488    dump_jobid(bsr->JobId);
489    dump_job(bsr->job);
490    dump_findex(bsr->FileIndex);
491    if (bsr->next) {
492       Dmsg0(-1, "\n");
493       dump_bsr(bsr->next);
494    }
495 }
496
497
498
499 /*********************************************************************
500  *
501  *      Free bsr resources
502  */
503
504 static void free_bsr_item(BSR *bsr)
505 {
506    if (!bsr) {
507       return;
508    }
509    free_bsr_item(bsr->next);
510    free(bsr);
511 }
512
513 void free_bsr(BSR *bsr)
514 {
515    if (!bsr) {
516       return;
517    }
518    free_bsr_item((BSR *)bsr->client);
519    free_bsr_item((BSR *)bsr->sessid);
520    free_bsr_item((BSR *)bsr->sesstime);
521    free_bsr_item((BSR *)bsr->volfile);
522    if (bsr->VolumeName) {
523       free(bsr->VolumeName);
524    }
525    free_bsr(bsr->next);
526    free(bsr);
527 }