]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/parse_bsr.c
e26ad8af47f1b62ecf0816e0e71a9c268cb7eaba
[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_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_file_index},
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    {NULL, NULL}
65
66 };
67
68 static BSR *new_bsr() 
69 {
70    BSR *bsr = (BSR *)malloc(sizeof(BSR));
71    memset(bsr, 0, sizeof(BSR));
72    return bsr;
73 }
74
75 /*********************************************************************
76  *
77  *      Parse Bootstrap file
78  *
79  */
80 BSR *parse_bsr(char *cf)
81 {
82    LEX *lc = NULL;
83    int token, i;
84    BSR *root_bsr = new_bsr();
85    BSR *bsr = root_bsr;
86
87    Dmsg0(200, "Enter parse_bsf()\n");
88    lc = lex_open_file(lc, cf);
89    while ((token=lex_get_token(lc)) != T_EOF) {
90       Dmsg1(150, "parse got token=%s\n", lex_tok_to_str(token));
91       if (token == T_EOL) {
92          continue;
93       }
94       if (token != T_IDENTIFIER) {
95          scan_err1(lc, "Expected a keyword identifier, got: %s", lc->str);
96       }
97       for (i=0; items[i].name; i++) {
98          if (strcasecmp(items[i].name, lc->str) == 0) {
99             token = lex_get_token(lc);
100             Dmsg1 (150, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
101             if (token != T_EQUALS) {
102                scan_err1(lc, "expected an equals, got: %s", lc->str);
103             }
104             Dmsg1(150, "calling handler for %s\n", items[i].name);
105             /* Call item handler */
106             bsr = items[i].handler(lc, bsr);
107             i = -1;
108             break;
109          }
110       }
111       if (i >= 0) {
112          Dmsg1(150, "Keyword = %s\n", lc->str);
113          scan_err1(lc, "Keyword %s not found", lc->str);
114       }
115
116    }
117    lc = lex_close_file(lc);
118    Dmsg0(200, "Leave parse_bsf()\n");
119    return root_bsr;
120 }
121
122 static BSR *store_vol(LEX *lc, BSR *bsr)
123 {
124    int token;
125     
126    token = lex_get_token(lc);
127    if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
128       scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
129    } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
130       scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
131          lc->str_len, MAX_RES_NAME_LENGTH);
132    } else {
133       if (bsr->VolumeName) {
134          bsr->next = new_bsr();
135          bsr = bsr->next;
136       }
137       bsr->VolumeName = bstrdup(lc->str);
138    }
139    scan_to_eol(lc);
140    return bsr;
141 }
142
143 static BSR *store_client(LEX *lc, BSR *bsr)
144 {
145    int token;
146    BSR_CLIENT *client;
147     
148    token = lex_get_token(lc);
149    if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
150       scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
151    } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
152       scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
153          lc->str_len, MAX_RES_NAME_LENGTH);
154    } else {
155       client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT));
156       memset(client, 0, sizeof(BSR_CLIENT));
157       client->ClientName = bstrdup(lc->str);
158       /* Add it to the end of the client chain */
159       if (!bsr->client) {
160          bsr->client = client;
161       } else {
162          BSR_CLIENT *bc = bsr->client;
163          for ( ;; ) {
164             if (bc->next) {
165                bc = bc->next;
166             } else {
167                bc->next = client;
168                break;
169             }
170          }
171       }
172    }
173    scan_to_eol(lc);
174    return bsr;
175 }
176
177 static BSR *store_job(LEX *lc, BSR *bsr)
178 {
179    int token;
180    BSR_JOB *job;
181     
182    token = lex_get_token(lc);
183    if (token != T_IDENTIFIER && token != T_STRING && token != T_QUOTED_STRING) {
184       scan_err1(lc, "expected an identifier or string, got: %s", lc->str);
185    } else if (lc->str_len > MAX_RES_NAME_LENGTH) {
186       scan_err3(lc, "name %s length %d too long, max is %d\n", lc->str, 
187          lc->str_len, MAX_RES_NAME_LENGTH);
188    } else {
189       job = (BSR_JOB *)malloc(sizeof(BSR_JOB));
190       memset(job, 0, sizeof(BSR_JOB));
191       job->Job = bstrdup(lc->str);
192       /* Add it to the end of the client chain */
193       if (!bsr->job) {
194          bsr->job = job;
195       } else {
196          /* Add to end of chain */
197          BSR_JOB *bc = bsr->job;
198          for ( ;bc->next; bc=bc->next)
199             { }
200          bc->next = job;
201       }
202    }
203    scan_to_eol(lc);
204    return bsr;
205 }
206
207 static BSR *store_file_index(LEX *lc, BSR *bsr)
208 {
209    int token;
210    int32_t FileIndex;
211    BSR_FINDEX *findex;
212
213
214    token = lex_get_token(lc);
215    if (token != T_NUMBER || !is_a_number(lc->str)) {
216       scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
217    } else {
218       errno = 0;
219       FileIndex = strtoul(lc->str, NULL, 10);
220       if (errno != 0) {
221          scan_err1(lc, "expected a integer number, got: %s", lc->str);
222       }
223       findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX));
224       memset(findex, 0, sizeof(BSR_FINDEX));
225       findex->FileIndex = FileIndex;
226       /* Add it to the end of the chain */
227       if (!bsr->FileIndex) {
228          bsr->FileIndex = findex;
229       } else {
230          /* Add to end of chain */
231          BSR_FINDEX *bs = bsr->FileIndex;
232          for ( ;bs->next; bs=bs->next)
233            {  }
234          bs->next = findex;
235       }
236    }
237    scan_to_eol(lc);
238    return bsr;
239 }
240
241
242 static BSR *store_jobid(LEX *lc, BSR *bsr)
243 {
244    int token;
245    uint32_t JobId;    
246    BSR_JOBID *jobid;
247
248
249    token = lex_get_token(lc);
250    if (token != T_NUMBER || !is_a_number(lc->str)) {
251       scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
252    } else {
253       errno = 0;
254       JobId = strtoul(lc->str, NULL, 10);
255       if (errno != 0) {
256          scan_err1(lc, "expected a integer number, got: %s", lc->str);
257       }
258       jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID));
259       memset(jobid, 0, sizeof(BSR_JOBID));
260       jobid->JobId = JobId;
261       /* Add it to the end of the chain */
262       if (!bsr->JobId) {
263          bsr->JobId = jobid;
264       } else {
265          /* Add to end of chain */
266          BSR_JOBID *bs = bsr->JobId;
267          for ( ;bs->next; bs=bs->next)
268            {  }
269          bs->next = jobid;
270       }
271    }
272    scan_to_eol(lc);
273    return bsr;
274 }
275
276 static BSR *store_jobtype(LEX *lc, BSR *bsr)
277 {
278    /* *****FIXME****** */
279    Dmsg0(-1, "JobType not yet implemented\n");
280    return bsr;
281 }
282
283
284 static BSR *store_joblevel(LEX *lc, BSR *bsr)
285 {
286    /* *****FIXME****** */
287    Dmsg0(-1, "JobLevel not yet implemented\n");
288    return bsr;
289 }
290
291
292
293 static BSR *store_sessid(LEX *lc, BSR *bsr)
294 {
295    int token;
296    uint32_t sessid1;
297    BSR_SESSID *sid;
298
299
300    token = lex_get_token(lc);
301    if (token != T_NUMBER || !is_a_number(lc->str)) {
302       scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
303    } else {
304       errno = 0;
305       sessid1 = strtoul(lc->str, NULL, 10);
306       if (errno != 0) {
307          scan_err1(lc, "expected a integer number, got: %s", lc->str);
308       }
309       sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID));
310       memset(sid, 0, sizeof(BSR_SESSID));
311       sid->sessid1 = sessid1;
312       /* Add it to the end of the chain */
313       if (!bsr->sessid) {
314          bsr->sessid = sid;
315       } else {
316          /* Add to end of chain */
317          BSR_SESSID *bs = bsr->sessid;
318          for ( ;bs->next; bs=bs->next)
319            {  }
320          bs->next = sid;
321       }
322    }
323    scan_to_eol(lc);
324    return bsr;
325 }
326
327 static BSR *store_sesstime(LEX *lc, BSR *bsr)
328 {
329    int token;
330    uint32_t sesstime;
331    BSR_SESSTIME *stime;
332
333
334    token = lex_get_token(lc);
335    if (token != T_NUMBER || !is_a_number(lc->str)) {
336       scan_err1(lc, "expected a positive integer number, got: %s", lc->str);
337    } else {
338       errno = 0;
339       sesstime = strtoul(lc->str, NULL, 10);
340       if (errno != 0) {
341          scan_err1(lc, "expected a integer number, got: %s", lc->str);
342       }
343       stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME));
344       memset(stime, 0, sizeof(BSR_SESSTIME));
345       stime->sesstime = sesstime;
346       /* Add it to the end of the chain */
347       if (!bsr->sesstime) {
348          bsr->sesstime = stime;
349       } else {
350          /* Add to end of chain */
351          BSR_SESSTIME *bs = bsr->sesstime;
352          for ( ;bs->next; bs=bs->next)
353             { }
354          bs->next = stime;
355       }
356    }
357    scan_to_eol(lc);
358    return bsr;
359 }
360
361 static BSR *store_include(LEX *lc, BSR *bsr)
362 {
363    scan_to_eol(lc);
364    return bsr;
365 }
366
367 static BSR *store_exclude(LEX *lc, BSR *bsr)
368 {
369    scan_to_eol(lc);
370    return bsr;
371 }
372
373 void dump_bsr(BSR *bsr)
374 {
375    if (!bsr) {
376       Dmsg0(-1, "BSR is NULL\n");
377       return;
378    }
379    Dmsg8(-1,   
380 "Next        : 0x%x\n"
381 "VolumeName  : %s\n"
382 "Client      : %s\n"
383 "Job         : %s\n"
384 "JobId       : %u\n"
385 "SessId      : %u\n"
386 "SessTime    : %u\n"
387 "FileIndex   : %d\n",
388                  bsr->next,
389                  bsr->VolumeName ? bsr->VolumeName : "*None*",
390                  bsr->client ? bsr->client->ClientName : "*None*",
391                  bsr->job ? bsr->job->Job : "*None*",
392                  bsr->JobId ? bsr->JobId->JobId : 0,
393                  bsr->sessid ? bsr->sessid->sessid1 : 0,
394                  bsr->sesstime ? bsr->sesstime->sesstime : 0,
395                  bsr->FileIndex ? bsr->FileIndex->FileIndex : 0);
396    if (bsr->next) {
397       Dmsg0(-1, "\n");
398       dump_bsr(bsr->next);
399    }
400 }
401
402
403 /*********************************************************************
404  *
405  *      Free bsr resources
406  */
407
408 static void free_bsr_item(BSR *bsr)
409 {
410    if (!bsr) {
411       return;
412    }
413    free_bsr_item(bsr->next);
414    free(bsr);
415 }
416
417 void free_bsr(BSR *bsr)
418 {
419    if (!bsr) {
420       return;
421    }
422    free_bsr_item((BSR *)bsr->client);
423    free_bsr_item((BSR *)bsr->sessid);
424    free_bsr_item((BSR *)bsr->sesstime);
425    if (bsr->VolumeName) {
426       free(bsr->VolumeName);
427    }
428    free_bsr(bsr->next);
429    free(bsr);
430 }