]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/parse_bsr.c
522b19b05a0907a3479dc1d3a2e724b07dd02594
[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    MA 02111-1307, USA.
25
26  */
27
28
29 #include "bacula.h"
30 #include "stored.h"
31
32 typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr);
33
34 static BSR *store_vol(LEX *lc, BSR *bsr);
35 static BSR *store_client(LEX *lc, BSR *bsr);
36 static BSR *store_job(LEX *lc, BSR *bsr);
37 static BSR *store_jobid(LEX *lc, BSR *bsr);
38 static BSR *store_jobtype(LEX *lc, BSR *bsr);
39 static BSR *store_joblevel(LEX *lc, BSR *bsr);
40 static BSR *store_findex(LEX *lc, BSR *bsr);
41 static BSR *store_sessid(LEX *lc, BSR *bsr);
42 static BSR *store_volfile(LEX *lc, BSR *bsr);
43 static BSR *store_sesstime(LEX *lc, BSR *bsr);
44 static BSR *store_include(LEX *lc, BSR *bsr);
45 static BSR *store_exclude(LEX *lc, BSR *bsr);
46
47 struct kw_items {
48    char *name;
49    ITEM_HANDLER *handler;
50 };
51
52 struct kw_items items[] = {
53    {"volume", store_vol},
54    {"client", store_client},
55    {"job", store_job},
56    {"jobid", store_jobid},
57    {"fileindex", store_findex},
58    {"jobtype", store_jobtype},
59    {"joblevel", store_joblevel},
60    {"volsessionid", store_sessid},
61    {"volsessiontime", store_sesstime},
62    {"include", store_include},
63    {"exclude", store_exclude},
64    {"volfile", store_volfile},
65    {NULL, NULL}
66
67 };
68
69 static BSR *new_bsr() 
70 {
71    BSR *bsr = (BSR *)malloc(sizeof(BSR));
72    memset(bsr, 0, sizeof(BSR));
73    return bsr;
74 }
75
76 /*
77  * Format a scanner error message 
78  */
79 static void s_err(char *file, int line, LEX *lc, char *msg, ...)
80 {
81    va_list arg_ptr;
82    char buf[MAXSTRING];
83
84    va_start(arg_ptr, msg);
85    bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
86    va_end(arg_ptr);
87      
88    e_msg(file, line, M_FATAL, 0, "Config error: %s\n\
89             : Line %d, col %d of file %s\n%s\n",
90       buf, lc->line_no, lc->col_no, lc->fname, lc->line);
91 }
92
93
94 /*********************************************************************
95  *
96  *      Parse Bootstrap file
97  *
98  */
99 BSR *parse_bsr(char *cf)
100 {
101    LEX *lc = NULL;
102    int token, i;
103    BSR *root_bsr = new_bsr();
104    BSR *bsr = root_bsr;
105
106    Dmsg0(200, "Enter parse_bsf()\n");
107    lc = lex_open_file(lc, cf, s_err);
108    while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
109       Dmsg1(150, "parse got token=%s\n", lex_tok_to_str(token));
110       if (token == T_EOL) {
111          continue;
112       }
113       for (i=0; items[i].name; i++) {
114          if (strcasecmp(items[i].name, lc->str) == 0) {
115             token = lex_get_token(lc, T_ALL);
116             Dmsg1 (150, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
117             if (token != T_EQUALS) {
118                scan_err1(lc, "expected an equals, got: %s", lc->str);
119                bsr = NULL;
120                break;
121             }
122             Dmsg1(100, "calling handler for %s\n", items[i].name);
123             /* Call item handler */
124             bsr = items[i].handler(lc, bsr);
125             i = -1;
126             break;
127          }
128       }
129       if (i >= 0) {
130          Dmsg1(150, "Keyword = %s\n", lc->str);
131          scan_err1(lc, "Keyword %s not found", lc->str);
132          break;
133       }
134       if (!bsr) {
135          break;
136       }
137    }
138    lc = lex_close_file(lc);
139    Dmsg0(200, "Leave parse_bsf()\n");
140    if (!bsr) {
141       free_bsr(root_bsr);
142       root_bsr = NULL;
143    }
144    return root_bsr;
145 }
146
147 static BSR *store_vol(LEX *lc, BSR *bsr)
148 {
149    int token;
150     
151    token = lex_get_token(lc, T_NAME);
152    if (token == T_ERROR) {
153       return NULL;
154    }
155    if (bsr->VolumeName) {
156       bsr->next = new_bsr();
157       bsr = bsr->next;
158    }
159    bsr->VolumeName = bstrdup(lc->str);
160    scan_to_eol(lc);
161    return bsr;
162 }
163
164 static BSR *store_client(LEX *lc, BSR *bsr)
165 {
166    int token;
167    BSR_CLIENT *client;
168     
169    for (;;) {
170       token = lex_get_token(lc, T_NAME);
171       if (token == T_ERROR) {
172          return NULL;
173       }
174       client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT));
175       memset(client, 0, sizeof(BSR_CLIENT));
176       strcpy(client->ClientName, lc->str);
177       /* Add it to the end of the client chain */
178       if (!bsr->client) {
179          bsr->client = client;
180       } else {
181          BSR_CLIENT *bc = bsr->client;
182          for ( ;bc->next; bc=bc->next)  
183             { }
184          bc->next = client;
185       }
186       token = lex_get_token(lc, T_ALL);
187       if (token != T_COMMA) {
188          break;
189       }
190    }
191    return bsr;
192 }
193
194 static BSR *store_job(LEX *lc, BSR *bsr)
195 {
196    int token;
197    BSR_JOB *job;
198     
199    for (;;) {
200       token = lex_get_token(lc, T_NAME);
201       if (token == T_ERROR) {
202          return NULL;
203       }
204       job = (BSR_JOB *)malloc(sizeof(BSR_JOB));
205       memset(job, 0, sizeof(BSR_JOB));
206       strcpy(job->Job, lc->str);
207       /* Add it to the end of the client chain */
208       if (!bsr->job) {
209          bsr->job = job;
210       } else {
211          /* Add to end of chain */
212          BSR_JOB *bc = bsr->job;
213          for ( ;bc->next; bc=bc->next)
214             { }
215          bc->next = job;
216       }
217       token = lex_get_token(lc, T_ALL);
218       if (token != T_COMMA) {
219          break;
220       }
221    }
222    return bsr;
223 }
224
225 static BSR *store_findex(LEX *lc, BSR *bsr)
226 {
227    int token;
228    BSR_FINDEX *findex;
229
230    for (;;) {
231       token = lex_get_token(lc, T_PINT32_RANGE);
232       if (token == T_ERROR) {
233          return NULL;
234       }
235       findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX));
236       memset(findex, 0, sizeof(BSR_FINDEX));
237       findex->findex = lc->pint32_val;
238       findex->findex2 = lc->pint32_val2;
239       /* Add it to the end of the chain */
240       if (!bsr->FileIndex) {
241          bsr->FileIndex = findex;
242       } else {
243          /* Add to end of chain */
244          BSR_FINDEX *bs = bsr->FileIndex;
245          for ( ;bs->next; bs=bs->next)
246             {  }
247          bs->next = findex;
248       }
249       token = lex_get_token(lc, T_ALL);
250       if (token != T_COMMA) {
251          break;
252       }
253    }
254    return bsr;
255 }
256
257
258 static BSR *store_jobid(LEX *lc, BSR *bsr)
259 {
260    int token;
261    BSR_JOBID *jobid;
262
263    for (;;) {
264       token = lex_get_token(lc, T_PINT32_RANGE);
265       if (token == T_ERROR) {
266          return NULL;
267       }
268       jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID));
269       memset(jobid, 0, sizeof(BSR_JOBID));
270       jobid->JobId = lc->pint32_val;
271       jobid->JobId2 = lc->pint32_val2;
272       /* Add it to the end of the chain */
273       if (!bsr->JobId) {
274          bsr->JobId = jobid;
275       } else {
276          /* Add to end of chain */
277          BSR_JOBID *bs = bsr->JobId;
278          for ( ;bs->next; bs=bs->next)
279             {  }
280          bs->next = jobid;
281       }
282       token = lex_get_token(lc, T_ALL);
283       if (token != T_COMMA) {
284          break;
285       }
286    }
287    return bsr;
288 }
289
290 static BSR *store_jobtype(LEX *lc, BSR *bsr)
291 {
292    /* *****FIXME****** */
293    Dmsg0(-1, "JobType not yet implemented\n");
294    return bsr;
295 }
296
297
298 static BSR *store_joblevel(LEX *lc, BSR *bsr)
299 {
300    /* *****FIXME****** */
301    Dmsg0(-1, "JobLevel not yet implemented\n");
302    return bsr;
303 }
304
305
306
307
308 /*
309  * Routine to handle Volume start/end file   
310  */
311 static BSR *store_volfile(LEX *lc, BSR *bsr)
312 {
313    int token;
314    BSR_VOLFILE *volfile;
315
316    for (;;) {
317       token = lex_get_token(lc, T_PINT32_RANGE);
318       if (token == T_ERROR) {
319          return NULL;
320       }
321       volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE));
322       memset(volfile, 0, sizeof(BSR_VOLFILE));
323       volfile->sfile = lc->pint32_val;
324       volfile->efile = lc->pint32_val2;
325       /* Add it to the end of the chain */
326       if (!bsr->volfile) {
327          bsr->volfile = volfile;
328       } else {
329          /* Add to end of chain */
330          BSR_VOLFILE *bs = bsr->volfile;
331          for ( ;bs->next; bs=bs->next)
332             {  }
333          bs->next = volfile;
334       }
335       token = lex_get_token(lc, T_ALL);
336       if (token != T_COMMA) {
337          break;
338       }
339    }
340    return bsr;
341 }
342
343
344
345 static BSR *store_sessid(LEX *lc, BSR *bsr)
346 {
347    int token;
348    BSR_SESSID *sid;
349
350    for (;;) {
351       token = lex_get_token(lc, T_PINT32_RANGE);
352       if (token == T_ERROR) {
353          return NULL;
354       }
355       sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID));
356       memset(sid, 0, sizeof(BSR_SESSID));
357       sid->sessid = lc->pint32_val;
358       sid->sessid2 = lc->pint32_val2;
359       /* Add it to the end of the chain */
360       if (!bsr->sessid) {
361          bsr->sessid = sid;
362       } else {
363          /* Add to end of chain */
364          BSR_SESSID *bs = bsr->sessid;
365          for ( ;bs->next; bs=bs->next)
366             {  }
367          bs->next = sid;
368       }
369       token = lex_get_token(lc, T_ALL);
370       if (token != T_COMMA) {
371          break;
372       }
373    }
374    return bsr;
375 }
376
377 static BSR *store_sesstime(LEX *lc, BSR *bsr)
378 {
379    int token;
380    BSR_SESSTIME *stime;
381
382    for (;;) {
383       token = lex_get_token(lc, T_PINT32);
384       if (token == T_ERROR) {
385          return NULL;
386       }
387       stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME));
388       memset(stime, 0, sizeof(BSR_SESSTIME));
389       stime->sesstime = lc->pint32_val;
390       /* Add it to the end of the chain */
391       if (!bsr->sesstime) {
392          bsr->sesstime = stime;
393       } else {
394          /* Add to end of chain */
395          BSR_SESSTIME *bs = bsr->sesstime;
396          for ( ;bs->next; bs=bs->next)
397             { }
398          bs->next = stime;
399       }
400       token = lex_get_token(lc, T_ALL);
401       if (token != T_COMMA) {
402          break;
403       }
404    }
405    return bsr;
406 }
407
408 static BSR *store_include(LEX *lc, BSR *bsr)
409 {
410    scan_to_eol(lc);
411    return bsr;
412 }
413
414 static BSR *store_exclude(LEX *lc, BSR *bsr)
415 {
416    scan_to_eol(lc);
417    return bsr;
418 }
419
420 void dump_volfile(BSR_VOLFILE *volfile)
421 {
422    if (volfile) {
423       Dmsg2(-1, "VolFile     : %u-%u\n", volfile->sfile, volfile->efile);
424       dump_volfile(volfile->next);
425    }
426 }
427
428 void dump_findex(BSR_FINDEX *FileIndex)
429 {
430    if (FileIndex) {
431       if (FileIndex->findex == FileIndex->findex2) {
432          Dmsg1(-1, "FileIndex   : %u\n", FileIndex->findex);
433       } else {
434          Dmsg2(-1, "FileIndex   : %u-%u\n", FileIndex->findex, FileIndex->findex2);
435       }
436       dump_findex(FileIndex->next);
437    }
438 }
439
440 void dump_jobid(BSR_JOBID *jobid)
441 {
442    if (jobid) {
443       if (jobid->JobId == jobid->JobId2) {
444          Dmsg1(-1, "JobId       : %u\n", jobid->JobId);
445       } else {
446          Dmsg2(-1, "JobId       : %u-%u\n", jobid->JobId, jobid->JobId2);
447       }
448       dump_jobid(jobid->next);
449    }
450 }
451
452 void dump_sessid(BSR_SESSID *sessid)
453 {
454    if (sessid) {
455       if (sessid->sessid == sessid->sessid2) {
456          Dmsg1(-1, "SessId      : %u\n", sessid->sessid);
457       } else {
458          Dmsg2(-1, "SessId      : %u-%u\n", sessid->sessid, sessid->sessid2);
459       }
460       dump_sessid(sessid->next);
461    }
462 }
463
464
465 void dump_client(BSR_CLIENT *client)
466 {
467    if (client) {
468       Dmsg1(-1, "Client      : %s\n", client->ClientName);
469       dump_client(client->next);
470    }
471 }
472
473 void dump_job(BSR_JOB *job)
474 {
475    if (job) {
476       Dmsg1(-1, "Job          : %s\n", job->Job);
477       dump_job(job->next);
478    }
479 }
480
481 void dump_sesstime(BSR_SESSTIME *sesstime)
482 {
483    if (sesstime) {
484       Dmsg1(-1, "SessTime    : %u\n", sesstime->sesstime);
485       dump_sesstime(sesstime->next);
486    }
487 }
488
489
490
491
492
493 void dump_bsr(BSR *bsr)
494 {
495    if (!bsr) {
496       Dmsg0(-1, "BSR is NULL\n");
497       return;
498    }
499    Dmsg2(-1,   
500 "Next        : 0x%x\n"
501 "VolumeName  : %s\n",
502                  bsr->next,
503                  bsr->VolumeName ? bsr->VolumeName : "*None*");
504    dump_sessid(bsr->sessid);
505    dump_sesstime(bsr->sesstime);
506    dump_volfile(bsr->volfile);
507    dump_client(bsr->client);
508    dump_jobid(bsr->JobId);
509    dump_job(bsr->job);
510    dump_findex(bsr->FileIndex);
511    if (bsr->next) {
512       Dmsg0(-1, "\n");
513       dump_bsr(bsr->next);
514    }
515 }
516
517
518
519 /*********************************************************************
520  *
521  *      Free bsr resources
522  */
523
524 static void free_bsr_item(BSR *bsr)
525 {
526    if (bsr) {
527       free_bsr_item(bsr->next);
528       free(bsr);
529    }
530 }
531
532 void free_bsr(BSR *bsr)
533 {
534    if (!bsr) {
535       return;
536    }
537    free_bsr_item((BSR *)bsr->client);
538    free_bsr_item((BSR *)bsr->sessid);
539    free_bsr_item((BSR *)bsr->sesstime);
540    free_bsr_item((BSR *)bsr->volfile);
541    free_bsr_item((BSR *)bsr->JobId);
542    free_bsr_item((BSR *)bsr->job);
543    free_bsr_item((BSR *)bsr->FileIndex);
544    free_bsr_item((BSR *)bsr->JobType);
545    free_bsr_item((BSR *)bsr->JobLevel);
546    if (bsr->VolumeName) {
547       free(bsr->VolumeName);
548    }
549    free_bsr(bsr->next);
550    free(bsr);
551 }
552
553 /*****************************************************************
554  * Routines for handling volumes     
555  */
556 VOL_LIST *new_vol()
557 {
558    VOL_LIST *vol;
559    vol = (VOL_LIST *)malloc(sizeof(VOL_LIST));
560    memset(vol, 0, sizeof(VOL_LIST));
561    return vol;
562 }
563
564 /* 
565  * Add current volume to end of list, only if the Volume
566  * is not already in the list.
567  *
568  *   returns: 1 if volume added
569  *            0 if volume already in list
570  */
571 int add_vol(JCR *jcr, VOL_LIST *vol)
572 {
573    VOL_LIST *next = jcr->VolList;
574
575    if (!next) {                       /* list empty ? */
576       jcr->VolList = vol;             /* yes, add volume */
577    } else {
578       for ( ; next->next; next=next->next) {
579          if (strcmp(vol->VolumeName, next->VolumeName) == 0) {
580             return 0;                 /* already in list */
581          }
582       }
583       if (strcmp(vol->VolumeName, next->VolumeName) == 0) {
584          return 0;                    /* already in list */
585       }
586       next->next = vol;               /* add volume */
587    }
588    return 1;
589 }
590
591 void free_vol_list(JCR *jcr)
592 {
593    VOL_LIST *next = jcr->VolList;
594    VOL_LIST *tmp;
595
596    for ( ; next; ) {
597       tmp = next->next;
598       free(next);
599       next = tmp;
600    }
601 }
602
603 void create_vol_list(JCR *jcr)
604 {
605    char *p, *n;
606    VOL_LIST *vol;
607
608    /* 
609     * Build a list of volume to be processed
610     */
611    jcr->NumVolumes = 0;
612    jcr->CurVolume = 1;
613    if (jcr->bsr) {
614       BSR *bsr = jcr->bsr;
615       strcpy(jcr->VolumeName, bsr->VolumeName); /* setup first volume */
616       for ( ; bsr; bsr=bsr->next) {
617          vol = new_vol();
618          strcpy(vol->VolumeName, bsr->VolumeName);
619          if (add_vol(jcr, vol)) {
620             jcr->NumVolumes++;
621             Dmsg1(400, "Added volume %s\n", vol->VolumeName);
622          } else {
623             Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName);
624             free((char *)vol);
625          }
626       }
627    } else {
628       /* This is the old way -- deprecated */ 
629       for (p = jcr->VolumeName; p && *p; ) {
630          n = strchr(p, '|');             /* volume name separator */
631          if (n) {
632             *n++ = 0;                    /* Terminate name */
633          }
634          vol = new_vol();
635          strcpy(vol->VolumeName, p);
636          if (add_vol(jcr, vol)) {
637             jcr->NumVolumes++;
638          } else {
639             free((char *)vol);
640          }
641          p = n;
642       }
643    }
644 }