1 /*
2 BAREOS® - Backup Archiving REcovery Open Sourced
3
4 Copyright (C) 2002-2012 Free Software Foundation Europe e.V.
5 Copyright (C) 2011-2012 Planets Communications B.V.
6 Copyright (C) 2013-2013 Bareos GmbH & Co. KG
7
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
11 in the file LICENSE.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.
22 */
23 /*
24 * Parse Bootstrap Records (used for restores)
25 *
26 * Kern Sibbald, June MMII
27 */
28
29 #include "include/bareos.h"
30 #include "jcr.h"
31 #include "stored/bsr.h"
32 #include "lib/berrno.h"
33 #include "lib/parse_bsr.h"
34
35 namespace libbareos {
36
37 typedef storagedaemon::BootStrapRecord*(
38 ITEM_HANDLER)(LEX* lc, storagedaemon::BootStrapRecord* bsr);
39
40 static storagedaemon::BootStrapRecord* store_vol(
41 LEX* lc,
42 storagedaemon::BootStrapRecord* bsr);
43 static storagedaemon::BootStrapRecord* store_mediatype(
44 LEX* lc,
45 storagedaemon::BootStrapRecord* bsr);
46 static storagedaemon::BootStrapRecord* StoreDevice(
47 LEX* lc,
48 storagedaemon::BootStrapRecord* bsr);
49 static storagedaemon::BootStrapRecord* store_client(
50 LEX* lc,
51 storagedaemon::BootStrapRecord* bsr);
52 static storagedaemon::BootStrapRecord* store_job(
53 LEX* lc,
54 storagedaemon::BootStrapRecord* bsr);
55 static storagedaemon::BootStrapRecord* store_jobid(
56 LEX* lc,
57 storagedaemon::BootStrapRecord* bsr);
58 static storagedaemon::BootStrapRecord* store_count(
59 LEX* lc,
60 storagedaemon::BootStrapRecord* bsr);
61 static storagedaemon::BootStrapRecord* StoreJobtype(
62 LEX* lc,
63 storagedaemon::BootStrapRecord* bsr);
64 static storagedaemon::BootStrapRecord* store_joblevel(
65 LEX* lc,
66 storagedaemon::BootStrapRecord* bsr);
67 static storagedaemon::BootStrapRecord* store_findex(
68 LEX* lc,
69 storagedaemon::BootStrapRecord* bsr);
70 static storagedaemon::BootStrapRecord* store_sessid(
71 LEX* lc,
72 storagedaemon::BootStrapRecord* bsr);
73 static storagedaemon::BootStrapRecord* store_volfile(
74 LEX* lc,
75 storagedaemon::BootStrapRecord* bsr);
76 static storagedaemon::BootStrapRecord* store_volblock(
77 LEX* lc,
78 storagedaemon::BootStrapRecord* bsr);
79 static storagedaemon::BootStrapRecord* store_voladdr(
80 LEX* lc,
81 storagedaemon::BootStrapRecord* bsr);
82 static storagedaemon::BootStrapRecord* store_sesstime(
83 LEX* lc,
84 storagedaemon::BootStrapRecord* bsr);
85 static storagedaemon::BootStrapRecord* store_include(
86 LEX* lc,
87 storagedaemon::BootStrapRecord* bsr);
88 static storagedaemon::BootStrapRecord* store_exclude(
89 LEX* lc,
90 storagedaemon::BootStrapRecord* bsr);
91 static storagedaemon::BootStrapRecord* store_stream(
92 LEX* lc,
93 storagedaemon::BootStrapRecord* bsr);
94 static storagedaemon::BootStrapRecord* store_slot(
95 LEX* lc,
96 storagedaemon::BootStrapRecord* bsr);
97 static storagedaemon::BootStrapRecord* store_fileregex(
98 LEX* lc,
99 storagedaemon::BootStrapRecord* bsr);
100 static storagedaemon::BootStrapRecord* store_nothing(
101 LEX* lc,
102 storagedaemon::BootStrapRecord* bsr);
103
104 struct kw_items {
105 const char* name;
106 ITEM_HANDLER* handler;
107 };
108
109 /*
110 * List of all keywords permitted in bsr files and their handlers
111 */
112 struct kw_items items[] = {{"volume", store_vol},
113 {"mediatype", store_mediatype},
114 {"client", store_client},
115 {"job", store_job},
116 {"jobid", store_jobid},
117 {"count", store_count},
118 {"fileindex", store_findex},
119 {"jobtype", StoreJobtype},
120 {"joblevel", store_joblevel},
121 {"volsessionid", store_sessid},
122 {"volsessiontime", store_sesstime},
123 {"include", store_include},
124 {"exclude", store_exclude},
125 {"volfile", store_volfile},
126 {"volblock", store_volblock},
127 {"voladdr", store_voladdr},
128 {"stream", store_stream},
129 {"slot", store_slot},
130 {"device", StoreDevice},
131 {"fileregex", store_fileregex},
132 {"storage", store_nothing},
133 {NULL, NULL}};
134
135 /*
136 * Create a storagedaemon::BootStrapRecord record
137 */
new_bsr()138 static storagedaemon::BootStrapRecord* new_bsr()
139 {
140 storagedaemon::BootStrapRecord* bsr = (storagedaemon::BootStrapRecord*)malloc(
141 sizeof(storagedaemon::BootStrapRecord));
142 memset(bsr, 0, sizeof(storagedaemon::BootStrapRecord));
143 return bsr;
144 }
145
146 /*
147 * Format a scanner error message
148 */
s_err(const char * file,int line,LEX * lc,const char * msg,...)149 static void s_err(const char* file, int line, LEX* lc, const char* msg, ...)
150 {
151 va_list ap;
152 int len, maxlen;
153 PoolMem buf(PM_NAME);
154 JobControlRecord* jcr = (JobControlRecord*)(lc->caller_ctx);
155
156 while (1) {
157 maxlen = buf.size() - 1;
158 va_start(ap, msg);
159 len = Bvsnprintf(buf.c_str(), maxlen, msg, ap);
160 va_end(ap);
161
162 if (len < 0 || len >= (maxlen - 5)) {
163 buf.ReallocPm(maxlen + maxlen / 2);
164 continue;
165 }
166
167 break;
168 }
169
170 if (jcr) {
171 Jmsg(jcr, M_FATAL, 0,
172 _("Bootstrap file error: %s\n"
173 " : Line %d, col %d of file %s\n%s\n"),
174 buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line);
175 } else {
176 e_msg(file, line, M_FATAL, 0,
177 _("Bootstrap file error: %s\n"
178 " : Line %d, col %d of file %s\n%s\n"),
179 buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line);
180 }
181 }
182
183 /*
184 * Format a scanner warning message
185 */
s_warn(const char * file,int line,LEX * lc,const char * msg,...)186 static void s_warn(const char* file, int line, LEX* lc, const char* msg, ...)
187 {
188 va_list ap;
189 int len, maxlen;
190 PoolMem buf(PM_NAME);
191 JobControlRecord* jcr = (JobControlRecord*)(lc->caller_ctx);
192
193 while (1) {
194 maxlen = buf.size() - 1;
195 va_start(ap, msg);
196 len = Bvsnprintf(buf.c_str(), maxlen, msg, ap);
197 va_end(ap);
198
199 if (len < 0 || len >= (maxlen - 5)) {
200 buf.ReallocPm(maxlen + maxlen / 2);
201 continue;
202 }
203
204 break;
205 }
206
207 if (jcr) {
208 Jmsg(jcr, M_WARNING, 0,
209 _("Bootstrap file warning: %s\n"
210 " : Line %d, col %d of file %s\n%s\n"),
211 buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line);
212 } else {
213 p_msg(file, line, 0,
214 _("Bootstrap file warning: %s\n"
215 " : Line %d, col %d of file %s\n%s\n"),
216 buf.c_str(), lc->line_no, lc->col_no, lc->fname, lc->line);
217 }
218 }
219
IsFastRejectionOk(storagedaemon::BootStrapRecord * bsr)220 static inline bool IsFastRejectionOk(storagedaemon::BootStrapRecord* bsr)
221 {
222 /*
223 * Although, this can be optimized, for the moment, require
224 * all bsrs to have both sesstime and sessid set before
225 * we do fast rejection.
226 */
227 for (; bsr; bsr = bsr->next) {
228 if (!(bsr->sesstime && bsr->sessid)) { return false; }
229 }
230 return true;
231 }
232
IsPositioningOk(storagedaemon::BootStrapRecord * bsr)233 static inline bool IsPositioningOk(storagedaemon::BootStrapRecord* bsr)
234 {
235 /*
236 * Every bsr should have a volfile entry and a volblock entry
237 * or a VolAddr
238 * if we are going to use positioning
239 */
240 for (; bsr; bsr = bsr->next) {
241 if (!((bsr->volfile && bsr->volblock) || bsr->voladdr)) { return false; }
242 }
243 return true;
244 }
245
246 /*
247 * Parse Bootstrap file
248 */
parse_bsr(JobControlRecord * jcr,char * fname)249 storagedaemon::BootStrapRecord* parse_bsr(JobControlRecord* jcr, char* fname)
250 {
251 LEX* lc = NULL;
252 int token, i;
253 storagedaemon::BootStrapRecord* root_bsr = new_bsr();
254 storagedaemon::BootStrapRecord* bsr = root_bsr;
255
256 Dmsg1(300, "Enter parse_bsf %s\n", fname);
257 if ((lc = lex_open_file(lc, fname, s_err, s_warn)) == NULL) {
258 BErrNo be;
259 Emsg2(M_ERROR_TERM, 0, _("Cannot open bootstrap file %s: %s\n"), fname,
260 be.bstrerror());
261 }
262 lc->caller_ctx = (void*)jcr;
263 while ((token = LexGetToken(lc, BCT_ALL)) != BCT_EOF) {
264 Dmsg1(300, "parse got token=%s\n", lex_tok_to_str(token));
265 if (token == BCT_EOL) { continue; }
266 for (i = 0; items[i].name; i++) {
267 if (Bstrcasecmp(items[i].name, lc->str)) {
268 token = LexGetToken(lc, BCT_ALL);
269 Dmsg1(300, "in BCT_IDENT got token=%s\n", lex_tok_to_str(token));
270 if (token != BCT_EQUALS) {
271 scan_err1(lc, "expected an equals, got: %s", lc->str);
272 bsr = NULL;
273 break;
274 }
275 Dmsg1(300, "calling handler for %s\n", items[i].name);
276 /*
277 * Call item handler
278 */
279 bsr = items[i].handler(lc, bsr);
280 i = -1;
281 break;
282 }
283 }
284 if (i >= 0) {
285 Dmsg1(300, "Keyword = %s\n", lc->str);
286 scan_err1(lc, "Keyword %s not found", lc->str);
287 bsr = NULL;
288 break;
289 }
290 if (!bsr) { break; }
291 }
292 lc = LexCloseFile(lc);
293 Dmsg0(300, "Leave parse_bsf()\n");
294 if (!bsr) {
295 FreeBsr(root_bsr);
296 root_bsr = NULL;
297 }
298 if (root_bsr) {
299 root_bsr->use_fast_rejection = IsFastRejectionOk(root_bsr);
300 root_bsr->use_positioning = IsPositioningOk(root_bsr);
301 }
302 for (bsr = root_bsr; bsr; bsr = bsr->next) { bsr->root = root_bsr; }
303 return root_bsr;
304 }
305
store_vol(LEX * lc,storagedaemon::BootStrapRecord * bsr)306 static storagedaemon::BootStrapRecord* store_vol(
307 LEX* lc,
308 storagedaemon::BootStrapRecord* bsr)
309 {
310 int token;
311 storagedaemon::BsrVolume* volume;
312 char *p, *n;
313
314 token = LexGetToken(lc, BCT_STRING);
315 if (token == BCT_ERROR) { return NULL; }
316 if (bsr->volume) {
317 bsr->next = new_bsr();
318 bsr->next->prev = bsr;
319 bsr = bsr->next;
320 }
321 /* This may actually be more than one volume separated by a |
322 * If so, separate them.
323 */
324 for (p = lc->str; p && *p;) {
325 n = strchr(p, '|');
326 if (n) { *n++ = 0; }
327 volume =
328 (storagedaemon::BsrVolume*)malloc(sizeof(storagedaemon::BsrVolume));
329 memset(volume, 0, sizeof(storagedaemon::BsrVolume));
330 bstrncpy(volume->VolumeName, p, sizeof(volume->VolumeName));
331
332 /*
333 * Add it to the end of the volume chain
334 */
335 if (!bsr->volume) {
336 bsr->volume = volume;
337 } else {
338 storagedaemon::BsrVolume* bc = bsr->volume;
339 for (; bc->next; bc = bc->next) {}
340 bc->next = volume;
341 }
342 p = n;
343 }
344 return bsr;
345 }
346
347 /*
348 * Shove the MediaType in each Volume in the current bsr\
349 */
store_mediatype(LEX * lc,storagedaemon::BootStrapRecord * bsr)350 static storagedaemon::BootStrapRecord* store_mediatype(
351 LEX* lc,
352 storagedaemon::BootStrapRecord* bsr)
353 {
354 int token;
355
356 token = LexGetToken(lc, BCT_STRING);
357 if (token == BCT_ERROR) { return NULL; }
358 if (!bsr->volume) {
359 Emsg1(M_ERROR, 0, _("MediaType %s in bsr at inappropriate place.\n"),
360 lc->str);
361 return bsr;
362 }
363 storagedaemon::BsrVolume* bv;
364 for (bv = bsr->volume; bv; bv = bv->next) {
365 bstrncpy(bv->MediaType, lc->str, sizeof(bv->MediaType));
366 }
367 return bsr;
368 }
369
store_nothing(LEX * lc,storagedaemon::BootStrapRecord * bsr)370 static storagedaemon::BootStrapRecord* store_nothing(
371 LEX* lc,
372 storagedaemon::BootStrapRecord* bsr)
373 {
374 int token;
375
376 token = LexGetToken(lc, BCT_STRING);
377 if (token == BCT_ERROR) { return NULL; }
378 return bsr;
379 }
380
381 /*
382 * Shove the Device name in each Volume in the current bsr
383 */
StoreDevice(LEX * lc,storagedaemon::BootStrapRecord * bsr)384 static storagedaemon::BootStrapRecord* StoreDevice(
385 LEX* lc,
386 storagedaemon::BootStrapRecord* bsr)
387 {
388 int token;
389
390 token = LexGetToken(lc, BCT_STRING);
391 if (token == BCT_ERROR) { return NULL; }
392 if (!bsr->volume) {
393 Emsg1(M_ERROR, 0, _("Device \"%s\" in bsr at inappropriate place.\n"),
394 lc->str);
395 return bsr;
396 }
397 storagedaemon::BsrVolume* bv;
398 for (bv = bsr->volume; bv; bv = bv->next) {
399 bstrncpy(bv->device, lc->str, sizeof(bv->device));
400 }
401 return bsr;
402 }
403
store_client(LEX * lc,storagedaemon::BootStrapRecord * bsr)404 static storagedaemon::BootStrapRecord* store_client(
405 LEX* lc,
406 storagedaemon::BootStrapRecord* bsr)
407 {
408 int token;
409 storagedaemon::BsrClient* client;
410
411 for (;;) {
412 token = LexGetToken(lc, BCT_NAME);
413 if (token == BCT_ERROR) { return NULL; }
414 client =
415 (storagedaemon::BsrClient*)malloc(sizeof(storagedaemon::BsrClient));
416 memset(client, 0, sizeof(storagedaemon::BsrClient));
417 bstrncpy(client->ClientName, lc->str, sizeof(client->ClientName));
418
419 /*
420 * Add it to the end of the client chain
421 */
422 if (!bsr->client) {
423 bsr->client = client;
424 } else {
425 storagedaemon::BsrClient* bc = bsr->client;
426 for (; bc->next; bc = bc->next) {}
427 bc->next = client;
428 }
429 token = LexGetToken(lc, BCT_ALL);
430 if (token != BCT_COMMA) { break; }
431 }
432 return bsr;
433 }
434
store_job(LEX * lc,storagedaemon::BootStrapRecord * bsr)435 static storagedaemon::BootStrapRecord* store_job(
436 LEX* lc,
437 storagedaemon::BootStrapRecord* bsr)
438 {
439 int token;
440 storagedaemon::BsrJob* job;
441
442 for (;;) {
443 token = LexGetToken(lc, BCT_NAME);
444 if (token == BCT_ERROR) { return NULL; }
445 job = (storagedaemon::BsrJob*)malloc(sizeof(storagedaemon::BsrJob));
446 memset(job, 0, sizeof(storagedaemon::BsrJob));
447 bstrncpy(job->Job, lc->str, sizeof(job->Job));
448
449 /*
450 * Add it to the end of the client chain
451 */
452 if (!bsr->job) {
453 bsr->job = job;
454 } else {
455 /*
456 * Add to end of chain
457 */
458 storagedaemon::BsrJob* bc = bsr->job;
459 for (; bc->next; bc = bc->next) {}
460 bc->next = job;
461 }
462 token = LexGetToken(lc, BCT_ALL);
463 if (token != BCT_COMMA) { break; }
464 }
465 return bsr;
466 }
467
store_findex(LEX * lc,storagedaemon::BootStrapRecord * bsr)468 static storagedaemon::BootStrapRecord* store_findex(
469 LEX* lc,
470 storagedaemon::BootStrapRecord* bsr)
471 {
472 int token;
473 storagedaemon::BsrFileIndex* findex;
474
475 for (;;) {
476 token = LexGetToken(lc, BCT_PINT32_RANGE);
477 if (token == BCT_ERROR) { return NULL; }
478 findex = (storagedaemon::BsrFileIndex*)malloc(
479 sizeof(storagedaemon::BsrFileIndex));
480 memset(findex, 0, sizeof(storagedaemon::BsrFileIndex));
481 findex->findex = lc->u.pint32_val;
482 findex->findex2 = lc->u2.pint32_val;
483
484 /*
485 * Add it to the end of the chain
486 */
487 if (!bsr->FileIndex) {
488 bsr->FileIndex = findex;
489 } else {
490 /*
491 * Add to end of chain
492 */
493 storagedaemon::BsrFileIndex* bs = bsr->FileIndex;
494 for (; bs->next; bs = bs->next) {}
495 bs->next = findex;
496 }
497 token = LexGetToken(lc, BCT_ALL);
498 if (token != BCT_COMMA) { break; }
499 }
500 return bsr;
501 }
502
store_jobid(LEX * lc,storagedaemon::BootStrapRecord * bsr)503 static storagedaemon::BootStrapRecord* store_jobid(
504 LEX* lc,
505 storagedaemon::BootStrapRecord* bsr)
506 {
507 int token;
508 storagedaemon::BsrJobid* jobid;
509
510 for (;;) {
511 token = LexGetToken(lc, BCT_PINT32_RANGE);
512 if (token == BCT_ERROR) { return NULL; }
513 jobid = (storagedaemon::BsrJobid*)malloc(sizeof(storagedaemon::BsrJobid));
514 memset(jobid, 0, sizeof(storagedaemon::BsrJobid));
515 jobid->JobId = lc->u.pint32_val;
516 jobid->JobId2 = lc->u2.pint32_val;
517
518 /*
519 * Add it to the end of the chain
520 */
521 if (!bsr->JobId) {
522 bsr->JobId = jobid;
523 } else {
524 /*
525 * Add to end of chain
526 */
527 storagedaemon::BsrJobid* bs = bsr->JobId;
528 for (; bs->next; bs = bs->next) {}
529 bs->next = jobid;
530 }
531 token = LexGetToken(lc, BCT_ALL);
532 if (token != BCT_COMMA) { break; }
533 }
534 return bsr;
535 }
536
store_count(LEX * lc,storagedaemon::BootStrapRecord * bsr)537 static storagedaemon::BootStrapRecord* store_count(
538 LEX* lc,
539 storagedaemon::BootStrapRecord* bsr)
540 {
541 int token;
542
543 token = LexGetToken(lc, BCT_PINT32);
544 if (token == BCT_ERROR) { return NULL; }
545 bsr->count = lc->u.pint32_val;
546 ScanToEol(lc);
547 return bsr;
548 }
549
store_fileregex(LEX * lc,storagedaemon::BootStrapRecord * bsr)550 static storagedaemon::BootStrapRecord* store_fileregex(
551 LEX* lc,
552 storagedaemon::BootStrapRecord* bsr)
553 {
554 int token;
555 int rc;
556
557 token = LexGetToken(lc, BCT_STRING);
558 if (token == BCT_ERROR) { return NULL; }
559
560 if (bsr->fileregex) free(bsr->fileregex);
561 bsr->fileregex = strdup(lc->str);
562
563 if (bsr->fileregex_re == NULL) {
564 bsr->fileregex_re = (regex_t*)malloc(sizeof(regex_t));
565 }
566
567 rc = regcomp(bsr->fileregex_re, bsr->fileregex, REG_EXTENDED | REG_NOSUB);
568 if (rc != 0) {
569 char prbuf[500];
570 regerror(rc, bsr->fileregex_re, prbuf, sizeof(prbuf));
571 Emsg2(M_ERROR, 0, _("REGEX '%s' compile error. ERR=%s\n"), bsr->fileregex,
572 prbuf);
573 return NULL;
574 }
575 return bsr;
576 }
577
StoreJobtype(LEX * lc,storagedaemon::BootStrapRecord * bsr)578 static storagedaemon::BootStrapRecord* StoreJobtype(
579 LEX* lc,
580 storagedaemon::BootStrapRecord* bsr)
581 {
582 /* *****FIXME****** */
583 Pmsg0(-1, _("JobType not yet implemented\n"));
584 return bsr;
585 }
586
store_joblevel(LEX * lc,storagedaemon::BootStrapRecord * bsr)587 static storagedaemon::BootStrapRecord* store_joblevel(
588 LEX* lc,
589 storagedaemon::BootStrapRecord* bsr)
590 {
591 /* *****FIXME****** */
592 Pmsg0(-1, _("JobLevel not yet implemented\n"));
593 return bsr;
594 }
595
596 /*
597 * Routine to handle Volume start/end file
598 */
store_volfile(LEX * lc,storagedaemon::BootStrapRecord * bsr)599 static storagedaemon::BootStrapRecord* store_volfile(
600 LEX* lc,
601 storagedaemon::BootStrapRecord* bsr)
602 {
603 int token;
604 storagedaemon::BsrVolumeFile* volfile;
605
606 for (;;) {
607 token = LexGetToken(lc, BCT_PINT32_RANGE);
608 if (token == BCT_ERROR) { return NULL; }
609 volfile = (storagedaemon::BsrVolumeFile*)malloc(
610 sizeof(storagedaemon::BsrVolumeFile));
611 memset(volfile, 0, sizeof(storagedaemon::BsrVolumeFile));
612 volfile->sfile = lc->u.pint32_val;
613 volfile->efile = lc->u2.pint32_val;
614
615 /*
616 * Add it to the end of the chain
617 */
618 if (!bsr->volfile) {
619 bsr->volfile = volfile;
620 } else {
621 /*
622 * Add to end of chain
623 */
624 storagedaemon::BsrVolumeFile* bs = bsr->volfile;
625 for (; bs->next; bs = bs->next) {}
626 bs->next = volfile;
627 }
628 token = LexGetToken(lc, BCT_ALL);
629 if (token != BCT_COMMA) { break; }
630 }
631 return bsr;
632 }
633
634 /*
635 * Routine to handle Volume start/end Block
636 */
store_volblock(LEX * lc,storagedaemon::BootStrapRecord * bsr)637 static storagedaemon::BootStrapRecord* store_volblock(
638 LEX* lc,
639 storagedaemon::BootStrapRecord* bsr)
640 {
641 int token;
642 storagedaemon::BsrVolumeBlock* volblock;
643
644 for (;;) {
645 token = LexGetToken(lc, BCT_PINT32_RANGE);
646 if (token == BCT_ERROR) { return NULL; }
647 volblock = (storagedaemon::BsrVolumeBlock*)malloc(
648 sizeof(storagedaemon::BsrVolumeBlock));
649 memset(volblock, 0, sizeof(storagedaemon::BsrVolumeBlock));
650 volblock->sblock = lc->u.pint32_val;
651 volblock->eblock = lc->u2.pint32_val;
652
653 /*
654 * Add it to the end of the chain
655 */
656 if (!bsr->volblock) {
657 bsr->volblock = volblock;
658 } else {
659 /*
660 * Add to end of chain
661 */
662 storagedaemon::BsrVolumeBlock* bs = bsr->volblock;
663 for (; bs->next; bs = bs->next) {}
664 bs->next = volblock;
665 }
666 token = LexGetToken(lc, BCT_ALL);
667 if (token != BCT_COMMA) { break; }
668 }
669 return bsr;
670 }
671
672 /*
673 * Routine to handle Volume start/end address
674 */
store_voladdr(LEX * lc,storagedaemon::BootStrapRecord * bsr)675 static storagedaemon::BootStrapRecord* store_voladdr(
676 LEX* lc,
677 storagedaemon::BootStrapRecord* bsr)
678 {
679 int token;
680 storagedaemon::BsrVolumeAddress* voladdr;
681
682 for (;;) {
683 token = LexGetToken(lc, BCT_PINT64_RANGE);
684 if (token == BCT_ERROR) { return NULL; }
685 voladdr = (storagedaemon::BsrVolumeAddress*)malloc(
686 sizeof(storagedaemon::BsrVolumeAddress));
687 memset(voladdr, 0, sizeof(storagedaemon::BsrVolumeAddress));
688 voladdr->saddr = lc->u.pint64_val;
689 voladdr->eaddr = lc->u2.pint64_val;
690
691 /*
692 * Add it to the end of the chain
693 */
694 if (!bsr->voladdr) {
695 bsr->voladdr = voladdr;
696 } else {
697 /*
698 * Add to end of chain
699 */
700 storagedaemon::BsrVolumeAddress* bs = bsr->voladdr;
701 for (; bs->next; bs = bs->next) {}
702 bs->next = voladdr;
703 }
704 token = LexGetToken(lc, BCT_ALL);
705 if (token != BCT_COMMA) { break; }
706 }
707 return bsr;
708 }
709
store_sessid(LEX * lc,storagedaemon::BootStrapRecord * bsr)710 static storagedaemon::BootStrapRecord* store_sessid(
711 LEX* lc,
712 storagedaemon::BootStrapRecord* bsr)
713 {
714 int token;
715 storagedaemon::BsrSessionId* sid;
716
717 for (;;) {
718 token = LexGetToken(lc, BCT_PINT32_RANGE);
719 if (token == BCT_ERROR) { return NULL; }
720 sid = (storagedaemon::BsrSessionId*)malloc(
721 sizeof(storagedaemon::BsrSessionId));
722 memset(sid, 0, sizeof(storagedaemon::BsrSessionId));
723 sid->sessid = lc->u.pint32_val;
724 sid->sessid2 = lc->u2.pint32_val;
725
726 /*
727 * Add it to the end of the chain
728 */
729 if (!bsr->sessid) {
730 bsr->sessid = sid;
731 } else {
732 /*
733 * Add to end of chain
734 */
735 storagedaemon::BsrSessionId* bs = bsr->sessid;
736 for (; bs->next; bs = bs->next) {}
737 bs->next = sid;
738 }
739 token = LexGetToken(lc, BCT_ALL);
740 if (token != BCT_COMMA) { break; }
741 }
742 return bsr;
743 }
744
store_sesstime(LEX * lc,storagedaemon::BootStrapRecord * bsr)745 static storagedaemon::BootStrapRecord* store_sesstime(
746 LEX* lc,
747 storagedaemon::BootStrapRecord* bsr)
748 {
749 int token;
750 storagedaemon::BsrSessionTime* stime;
751
752 for (;;) {
753 token = LexGetToken(lc, BCT_PINT32);
754 if (token == BCT_ERROR) { return NULL; }
755 stime = (storagedaemon::BsrSessionTime*)malloc(
756 sizeof(storagedaemon::BsrSessionTime));
757 memset(stime, 0, sizeof(storagedaemon::BsrSessionTime));
758 stime->sesstime = lc->u.pint32_val;
759
760 /*
761 * Add it to the end of the chain
762 */
763 if (!bsr->sesstime) {
764 bsr->sesstime = stime;
765 } else {
766 /*
767 * Add to end of chain
768 */
769 storagedaemon::BsrSessionTime* bs = bsr->sesstime;
770 for (; bs->next; bs = bs->next) {}
771 bs->next = stime;
772 }
773 token = LexGetToken(lc, BCT_ALL);
774 if (token != BCT_COMMA) { break; }
775 }
776 return bsr;
777 }
778
store_stream(LEX * lc,storagedaemon::BootStrapRecord * bsr)779 static storagedaemon::BootStrapRecord* store_stream(
780 LEX* lc,
781 storagedaemon::BootStrapRecord* bsr)
782 {
783 int token;
784 storagedaemon::BsrStream* stream;
785
786 for (;;) {
787 token = LexGetToken(lc, BCT_INT32);
788 if (token == BCT_ERROR) { return NULL; }
789 stream =
790 (storagedaemon::BsrStream*)malloc(sizeof(storagedaemon::BsrStream));
791 memset(stream, 0, sizeof(storagedaemon::BsrStream));
792 stream->stream = lc->u.int32_val;
793
794 /*
795 * Add it to the end of the chain
796 */
797 if (!bsr->stream) {
798 bsr->stream = stream;
799 } else {
800 /*
801 * Add to end of chain
802 */
803 storagedaemon::BsrStream* bs = bsr->stream;
804 for (; bs->next; bs = bs->next) {}
805 bs->next = stream;
806 }
807 token = LexGetToken(lc, BCT_ALL);
808 if (token != BCT_COMMA) { break; }
809 }
810 return bsr;
811 }
812
store_slot(LEX * lc,storagedaemon::BootStrapRecord * bsr)813 static storagedaemon::BootStrapRecord* store_slot(
814 LEX* lc,
815 storagedaemon::BootStrapRecord* bsr)
816 {
817 int token;
818
819 token = LexGetToken(lc, BCT_PINT32);
820 if (token == BCT_ERROR) { return NULL; }
821 if (!bsr->volume) {
822 Emsg1(M_ERROR, 0, _("Slot %d in bsr at inappropriate place.\n"),
823 lc->u.pint32_val);
824 return bsr;
825 }
826 bsr->volume->Slot = lc->u.pint32_val;
827 ScanToEol(lc);
828 return bsr;
829 }
830
store_include(LEX * lc,storagedaemon::BootStrapRecord * bsr)831 static storagedaemon::BootStrapRecord* store_include(
832 LEX* lc,
833 storagedaemon::BootStrapRecord* bsr)
834 {
835 ScanToEol(lc);
836 return bsr;
837 }
838
store_exclude(LEX * lc,storagedaemon::BootStrapRecord * bsr)839 static storagedaemon::BootStrapRecord* store_exclude(
840 LEX* lc,
841 storagedaemon::BootStrapRecord* bsr)
842 {
843 ScanToEol(lc);
844 return bsr;
845 }
846
DumpVolfile(storagedaemon::BsrVolumeFile * volfile)847 static inline void DumpVolfile(storagedaemon::BsrVolumeFile* volfile)
848 {
849 if (volfile) {
850 Pmsg2(-1, _("VolFile : %u-%u\n"), volfile->sfile, volfile->efile);
851 DumpVolfile(volfile->next);
852 }
853 }
854
DumpVolblock(storagedaemon::BsrVolumeBlock * volblock)855 static inline void DumpVolblock(storagedaemon::BsrVolumeBlock* volblock)
856 {
857 if (volblock) {
858 Pmsg2(-1, _("VolBlock : %u-%u\n"), volblock->sblock, volblock->eblock);
859 DumpVolblock(volblock->next);
860 }
861 }
862
DumpVoladdr(storagedaemon::BsrVolumeAddress * voladdr)863 static inline void DumpVoladdr(storagedaemon::BsrVolumeAddress* voladdr)
864 {
865 if (voladdr) {
866 Pmsg2(-1, _("VolAddr : %llu-%llu\n"), voladdr->saddr, voladdr->eaddr);
867 DumpVoladdr(voladdr->next);
868 }
869 }
870
DumpFindex(storagedaemon::BsrFileIndex * FileIndex)871 static inline void DumpFindex(storagedaemon::BsrFileIndex* FileIndex)
872 {
873 if (FileIndex) {
874 if (FileIndex->findex == FileIndex->findex2) {
875 Pmsg1(-1, _("FileIndex : %u\n"), FileIndex->findex);
876 } else {
877 Pmsg2(-1, _("FileIndex : %u-%u\n"), FileIndex->findex,
878 FileIndex->findex2);
879 }
880 DumpFindex(FileIndex->next);
881 }
882 }
883
DumpJobid(storagedaemon::BsrJobid * jobid)884 static inline void DumpJobid(storagedaemon::BsrJobid* jobid)
885 {
886 if (jobid) {
887 if (jobid->JobId == jobid->JobId2) {
888 Pmsg1(-1, _("JobId : %u\n"), jobid->JobId);
889 } else {
890 Pmsg2(-1, _("JobId : %u-%u\n"), jobid->JobId, jobid->JobId2);
891 }
892 DumpJobid(jobid->next);
893 }
894 }
895
DumpSessid(storagedaemon::BsrSessionId * sessid)896 static inline void DumpSessid(storagedaemon::BsrSessionId* sessid)
897 {
898 if (sessid) {
899 if (sessid->sessid == sessid->sessid2) {
900 Pmsg1(-1, _("SessId : %u\n"), sessid->sessid);
901 } else {
902 Pmsg2(-1, _("SessId : %u-%u\n"), sessid->sessid, sessid->sessid2);
903 }
904 DumpSessid(sessid->next);
905 }
906 }
907
DumpVolume(storagedaemon::BsrVolume * volume)908 static inline void DumpVolume(storagedaemon::BsrVolume* volume)
909 {
910 if (volume) {
911 Pmsg1(-1, _("VolumeName : %s\n"), volume->VolumeName);
912 Pmsg1(-1, _(" MediaType : %s\n"), volume->MediaType);
913 Pmsg1(-1, _(" Device : %s\n"), volume->device);
914 Pmsg1(-1, _(" Slot : %d\n"), volume->Slot);
915 DumpVolume(volume->next);
916 }
917 }
918
DumpClient(storagedaemon::BsrClient * client)919 static inline void DumpClient(storagedaemon::BsrClient* client)
920 {
921 if (client) {
922 Pmsg1(-1, _("Client : %s\n"), client->ClientName);
923 DumpClient(client->next);
924 }
925 }
926
dump_job(storagedaemon::BsrJob * job)927 static inline void dump_job(storagedaemon::BsrJob* job)
928 {
929 if (job) {
930 Pmsg1(-1, _("Job : %s\n"), job->Job);
931 dump_job(job->next);
932 }
933 }
934
DumpSesstime(storagedaemon::BsrSessionTime * sesstime)935 static inline void DumpSesstime(storagedaemon::BsrSessionTime* sesstime)
936 {
937 if (sesstime) {
938 Pmsg1(-1, _("SessTime : %u\n"), sesstime->sesstime);
939 DumpSesstime(sesstime->next);
940 }
941 }
942
DumpBsr(storagedaemon::BootStrapRecord * bsr,bool recurse)943 void DumpBsr(storagedaemon::BootStrapRecord* bsr, bool recurse)
944 {
945 int save_debug = debug_level;
946 debug_level = 1;
947 if (!bsr) {
948 Pmsg0(-1, _("storagedaemon::BootStrapRecord is NULL\n"));
949 debug_level = save_debug;
950 return;
951 }
952 Pmsg1(-1, _("Next : 0x%x\n"), bsr->next);
953 Pmsg1(-1, _("Root bsr : 0x%x\n"), bsr->root);
954 DumpVolume(bsr->volume);
955 DumpSessid(bsr->sessid);
956 DumpSesstime(bsr->sesstime);
957 DumpVolfile(bsr->volfile);
958 DumpVolblock(bsr->volblock);
959 DumpVoladdr(bsr->voladdr);
960 DumpClient(bsr->client);
961 DumpJobid(bsr->JobId);
962 dump_job(bsr->job);
963 DumpFindex(bsr->FileIndex);
964 if (bsr->count) {
965 Pmsg1(-1, _("count : %u\n"), bsr->count);
966 Pmsg1(-1, _("found : %u\n"), bsr->found);
967 }
968
969 Pmsg1(-1, _("done : %s\n"), bsr->done ? _("yes") : _("no"));
970 Pmsg1(-1, _("positioning : %d\n"), bsr->use_positioning);
971 Pmsg1(-1, _("fast_reject : %d\n"), bsr->use_fast_rejection);
972 if (recurse && bsr->next) {
973 Pmsg0(-1, "\n");
974 DumpBsr(bsr->next, true);
975 }
976 debug_level = save_debug;
977 }
978
979 /*
980 * Free bsr resources
981 */
FreeBsrItem(storagedaemon::BootStrapRecord * bsr)982 static inline void FreeBsrItem(storagedaemon::BootStrapRecord* bsr)
983 {
984 if (bsr) {
985 FreeBsrItem(bsr->next);
986 free(bsr);
987 }
988 }
989
990 /*
991 * Remove a single item from the bsr tree
992 */
RemoveBsr(storagedaemon::BootStrapRecord * bsr)993 static inline void RemoveBsr(storagedaemon::BootStrapRecord* bsr)
994 {
995 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->volume);
996 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->client);
997 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->sessid);
998 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->sesstime);
999 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->volfile);
1000 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->volblock);
1001 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->voladdr);
1002 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->JobId);
1003 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->job);
1004 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->FileIndex);
1005 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->JobType);
1006 FreeBsrItem((storagedaemon::BootStrapRecord*)bsr->JobLevel);
1007 if (bsr->fileregex) { free(bsr->fileregex); }
1008 if (bsr->fileregex_re) {
1009 regfree(bsr->fileregex_re);
1010 free(bsr->fileregex_re);
1011 }
1012 if (bsr->attr) { FreeAttr(bsr->attr); }
1013 if (bsr->next) { bsr->next->prev = bsr->prev; }
1014 if (bsr->prev) { bsr->prev->next = bsr->next; }
1015 free(bsr);
1016 }
1017
1018 /*
1019 * Free all bsrs in chain
1020 */
FreeBsr(storagedaemon::BootStrapRecord * bsr)1021 void FreeBsr(storagedaemon::BootStrapRecord* bsr)
1022 {
1023 storagedaemon::BootStrapRecord* next_bsr;
1024
1025 if (!bsr) { return; }
1026 next_bsr = bsr->next;
1027
1028 /*
1029 * Remove (free) current bsr
1030 */
1031 RemoveBsr(bsr);
1032
1033 /*
1034 * Now get the next one
1035 */
1036 FreeBsr(next_bsr);
1037 }
1038
1039 } /* namespace libbareos */
1040