2 * Parse a Bootstrap Records (used for restores)
4 * Kern Sibbald, June MMII
9 Bacula® - The Network Backup Solution
11 Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
13 The main author of Bacula is Kern Sibbald, with contributions from
14 many others, a complete list can be found in the file AUTHORS.
15 This program is Free Software; you can redistribute it and/or
16 modify it under the terms of version two of the GNU General Public
17 License as published by the Free Software Foundation and included
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 Bacula® is a registered trademark of Kern Sibbald.
31 The licensor of Bacula is the Free Software Foundation Europe
32 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
33 Switzerland, email:ftf@fsfeurope.org.
40 typedef BSR * (ITEM_HANDLER)(LEX *lc, BSR *bsr);
42 static BSR *store_vol(LEX *lc, BSR *bsr);
43 static BSR *store_mediatype(LEX *lc, BSR *bsr);
44 static BSR *store_device(LEX *lc, BSR *bsr);
45 static BSR *store_client(LEX *lc, BSR *bsr);
46 static BSR *store_job(LEX *lc, BSR *bsr);
47 static BSR *store_jobid(LEX *lc, BSR *bsr);
48 static BSR *store_count(LEX *lc, BSR *bsr);
49 static BSR *store_jobtype(LEX *lc, BSR *bsr);
50 static BSR *store_joblevel(LEX *lc, BSR *bsr);
51 static BSR *store_findex(LEX *lc, BSR *bsr);
52 static BSR *store_sessid(LEX *lc, BSR *bsr);
53 static BSR *store_volfile(LEX *lc, BSR *bsr);
54 static BSR *store_volblock(LEX *lc, BSR *bsr);
55 static BSR *store_sesstime(LEX *lc, BSR *bsr);
56 static BSR *store_include(LEX *lc, BSR *bsr);
57 static BSR *store_exclude(LEX *lc, BSR *bsr);
58 static BSR *store_stream(LEX *lc, BSR *bsr);
59 static BSR *store_slot(LEX *lc, BSR *bsr);
60 static BSR *store_fileregex(LEX *lc, BSR *bsr);
61 static bool is_fast_rejection_ok(BSR *bsr);
62 static bool is_positioning_ok(BSR *bsr);
66 ITEM_HANDLER *handler;
70 * List of all keywords permitted in bsr files and their handlers
72 struct kw_items items[] = {
73 {"volume", store_vol},
74 {"mediatype", store_mediatype},
75 {"client", store_client},
77 {"jobid", store_jobid},
78 {"count", store_count},
79 {"fileindex", store_findex},
80 {"jobtype", store_jobtype},
81 {"joblevel", store_joblevel},
82 {"volsessionid", store_sessid},
83 {"volsessiontime", store_sesstime},
84 {"include", store_include},
85 {"exclude", store_exclude},
86 {"volfile", store_volfile},
87 {"volblock", store_volblock},
88 {"stream", store_stream},
90 {"device", store_device},
91 {"fileregex", store_fileregex},
100 BSR *bsr = (BSR *)malloc(sizeof(BSR));
101 memset(bsr, 0, sizeof(BSR));
106 * Format a scanner error message
108 static void s_err(const char *file, int line, LEX *lc, const char *msg, ...)
110 JCR *jcr = (JCR *)(lc->caller_ctx);
114 va_start(arg_ptr, msg);
115 bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
119 Jmsg(jcr, M_FATAL, 0, _("Bootstrap file error: %s\n"
120 " : Line %d, col %d of file %s\n%s\n"),
121 buf, lc->line_no, lc->col_no, lc->fname, lc->line);
123 e_msg(file, line, M_FATAL, 0, _("Bootstrap file error: %s\n"
124 " : Line %d, col %d of file %s\n%s\n"),
125 buf, lc->line_no, lc->col_no, lc->fname, lc->line);
130 /*********************************************************************
132 * Parse Bootstrap file
135 BSR *parse_bsr(JCR *jcr, char *fname)
139 BSR *root_bsr = new_bsr();
142 Dmsg1(300, "Enter parse_bsf %s\n", fname);
143 if ((lc = lex_open_file(lc, fname, s_err)) == NULL) {
145 Emsg2(M_ERROR_TERM, 0, _("Cannot open bootstrap file %s: %s\n"),
146 fname, be.bstrerror());
148 lc->caller_ctx = (void *)jcr;
149 while ((token=lex_get_token(lc, T_ALL)) != T_EOF) {
150 Dmsg1(300, "parse got token=%s\n", lex_tok_to_str(token));
151 if (token == T_EOL) {
154 for (i=0; items[i].name; i++) {
155 if (strcasecmp(items[i].name, lc->str) == 0) {
156 token = lex_get_token(lc, T_ALL);
157 Dmsg1 (300, "in T_IDENT got token=%s\n", lex_tok_to_str(token));
158 if (token != T_EQUALS) {
159 scan_err1(lc, "expected an equals, got: %s", lc->str);
163 Dmsg1(300, "calling handler for %s\n", items[i].name);
164 /* Call item handler */
165 bsr = items[i].handler(lc, bsr);
171 Dmsg1(300, "Keyword = %s\n", lc->str);
172 scan_err1(lc, "Keyword %s not found", lc->str);
180 lc = lex_close_file(lc);
181 Dmsg0(300, "Leave parse_bsf()\n");
187 root_bsr->use_fast_rejection = is_fast_rejection_ok(root_bsr);
188 root_bsr->use_positioning = is_positioning_ok(root_bsr);
190 for (bsr=root_bsr; bsr; bsr=bsr->next) {
191 bsr->root = root_bsr;
196 static bool is_fast_rejection_ok(BSR *bsr)
199 * Although, this can be optimized, for the moment, require
200 * all bsrs to have both sesstime and sessid set before
201 * we do fast rejection.
203 for ( ; bsr; bsr=bsr->next) {
204 if (!(bsr->sesstime && bsr->sessid)) {
211 static bool is_positioning_ok(BSR *bsr)
214 * Every bsr should have a volfile entry and a volblock entry
215 * if we are going to use positioning
217 for ( ; bsr; bsr=bsr->next) {
218 if (!bsr->volfile || !bsr->volblock) {
226 static BSR *store_vol(LEX *lc, BSR *bsr)
232 token = lex_get_token(lc, T_STRING);
233 if (token == T_ERROR) {
237 bsr->next = new_bsr();
238 bsr->next->prev = bsr;
241 /* This may actually be more than one volume separated by a |
242 * If so, separate them.
244 for (p=lc->str; p && *p; ) {
249 volume = (BSR_VOLUME *)malloc(sizeof(BSR_VOLUME));
250 memset(volume, 0, sizeof(BSR_VOLUME));
251 bstrncpy(volume->VolumeName, p, sizeof(volume->VolumeName));
252 /* Add it to the end of the volume chain */
254 bsr->volume = volume;
256 BSR_VOLUME *bc = bsr->volume;
257 for ( ;bc->next; bc=bc->next)
266 /* Shove the MediaType in each Volume in the current bsr */
267 static BSR *store_mediatype(LEX *lc, BSR *bsr)
271 token = lex_get_token(lc, T_STRING);
272 if (token == T_ERROR) {
276 Emsg1(M_ERROR,0, _("MediaType %s in bsr at inappropriate place.\n"),
281 for (bv=bsr->volume; bv; bv=bv->next) {
282 bstrncpy(bv->MediaType, lc->str, sizeof(bv->MediaType));
287 /* Shove the Device name in each Volume in the current bsr */
288 static BSR *store_device(LEX *lc, BSR *bsr)
292 token = lex_get_token(lc, T_STRING);
293 if (token == T_ERROR) {
297 Emsg1(M_ERROR,0, _("Device \"%s\" in bsr at inappropriate place.\n"),
302 for (bv=bsr->volume; bv; bv=bv->next) {
303 bstrncpy(bv->device, lc->str, sizeof(bv->device));
310 static BSR *store_client(LEX *lc, BSR *bsr)
316 token = lex_get_token(lc, T_NAME);
317 if (token == T_ERROR) {
320 client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT));
321 memset(client, 0, sizeof(BSR_CLIENT));
322 bstrncpy(client->ClientName, lc->str, sizeof(client->ClientName));
323 /* Add it to the end of the client chain */
325 bsr->client = client;
327 BSR_CLIENT *bc = bsr->client;
328 for ( ;bc->next; bc=bc->next)
332 token = lex_get_token(lc, T_ALL);
333 if (token != T_COMMA) {
340 static BSR *store_job(LEX *lc, BSR *bsr)
346 token = lex_get_token(lc, T_NAME);
347 if (token == T_ERROR) {
350 job = (BSR_JOB *)malloc(sizeof(BSR_JOB));
351 memset(job, 0, sizeof(BSR_JOB));
352 bstrncpy(job->Job, lc->str, sizeof(job->Job));
353 /* Add it to the end of the client chain */
357 /* Add to end of chain */
358 BSR_JOB *bc = bsr->job;
359 for ( ;bc->next; bc=bc->next)
363 token = lex_get_token(lc, T_ALL);
364 if (token != T_COMMA) {
371 static BSR *store_findex(LEX *lc, BSR *bsr)
377 token = lex_get_token(lc, T_PINT32_RANGE);
378 if (token == T_ERROR) {
381 findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX));
382 memset(findex, 0, sizeof(BSR_FINDEX));
383 findex->findex = lc->pint32_val;
384 findex->findex2 = lc->pint32_val2;
385 /* Add it to the end of the chain */
386 if (!bsr->FileIndex) {
387 bsr->FileIndex = findex;
389 /* Add to end of chain */
390 BSR_FINDEX *bs = bsr->FileIndex;
391 for ( ;bs->next; bs=bs->next)
395 token = lex_get_token(lc, T_ALL);
396 if (token != T_COMMA) {
404 static BSR *store_jobid(LEX *lc, BSR *bsr)
410 token = lex_get_token(lc, T_PINT32_RANGE);
411 if (token == T_ERROR) {
414 jobid = (BSR_JOBID *)malloc(sizeof(BSR_JOBID));
415 memset(jobid, 0, sizeof(BSR_JOBID));
416 jobid->JobId = lc->pint32_val;
417 jobid->JobId2 = lc->pint32_val2;
418 /* Add it to the end of the chain */
422 /* Add to end of chain */
423 BSR_JOBID *bs = bsr->JobId;
424 for ( ;bs->next; bs=bs->next)
428 token = lex_get_token(lc, T_ALL);
429 if (token != T_COMMA) {
437 static BSR *store_count(LEX *lc, BSR *bsr)
441 token = lex_get_token(lc, T_PINT32);
442 if (token == T_ERROR) {
445 bsr->count = lc->pint32_val;
450 static BSR *store_fileregex(LEX *lc, BSR *bsr)
455 token = lex_get_token(lc, T_STRING);
456 if (token == T_ERROR) {
460 if (bsr->fileregex) free(bsr->fileregex);
461 bsr->fileregex = bstrdup(lc->str);
463 if (bsr->fileregex_re == NULL)
464 bsr->fileregex_re = (regex_t *)bmalloc(sizeof(regex_t));
466 rc = regcomp(bsr->fileregex_re, bsr->fileregex, REG_EXTENDED|REG_NOSUB);
469 regerror(rc, bsr->fileregex_re, prbuf, sizeof(prbuf));
470 Emsg2(M_ERROR, 0, _("REGEX '%s' compile error. ERR=%s\n"),
471 bsr->fileregex, prbuf);
477 static BSR *store_jobtype(LEX *lc, BSR *bsr)
479 /* *****FIXME****** */
480 Pmsg0(-1, _("JobType not yet implemented\n"));
485 static BSR *store_joblevel(LEX *lc, BSR *bsr)
487 /* *****FIXME****** */
488 Pmsg0(-1, _("JobLevel not yet implemented\n"));
496 * Routine to handle Volume start/end file
498 static BSR *store_volfile(LEX *lc, BSR *bsr)
501 BSR_VOLFILE *volfile;
504 token = lex_get_token(lc, T_PINT32_RANGE);
505 if (token == T_ERROR) {
508 volfile = (BSR_VOLFILE *)malloc(sizeof(BSR_VOLFILE));
509 memset(volfile, 0, sizeof(BSR_VOLFILE));
510 volfile->sfile = lc->pint32_val;
511 volfile->efile = lc->pint32_val2;
512 /* Add it to the end of the chain */
514 bsr->volfile = volfile;
516 /* Add to end of chain */
517 BSR_VOLFILE *bs = bsr->volfile;
518 for ( ;bs->next; bs=bs->next)
522 token = lex_get_token(lc, T_ALL);
523 if (token != T_COMMA) {
532 * Routine to handle Volume start/end Block
534 static BSR *store_volblock(LEX *lc, BSR *bsr)
537 BSR_VOLBLOCK *volblock;
540 token = lex_get_token(lc, T_PINT32_RANGE);
541 if (token == T_ERROR) {
544 volblock = (BSR_VOLBLOCK *)malloc(sizeof(BSR_VOLBLOCK));
545 memset(volblock, 0, sizeof(BSR_VOLBLOCK));
546 volblock->sblock = lc->pint32_val;
547 volblock->eblock = lc->pint32_val2;
548 /* Add it to the end of the chain */
549 if (!bsr->volblock) {
550 bsr->volblock = volblock;
552 /* Add to end of chain */
553 BSR_VOLBLOCK *bs = bsr->volblock;
554 for ( ;bs->next; bs=bs->next)
558 token = lex_get_token(lc, T_ALL);
559 if (token != T_COMMA) {
567 static BSR *store_sessid(LEX *lc, BSR *bsr)
573 token = lex_get_token(lc, T_PINT32_RANGE);
574 if (token == T_ERROR) {
577 sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID));
578 memset(sid, 0, sizeof(BSR_SESSID));
579 sid->sessid = lc->pint32_val;
580 sid->sessid2 = lc->pint32_val2;
581 /* Add it to the end of the chain */
585 /* Add to end of chain */
586 BSR_SESSID *bs = bsr->sessid;
587 for ( ;bs->next; bs=bs->next)
591 token = lex_get_token(lc, T_ALL);
592 if (token != T_COMMA) {
599 static BSR *store_sesstime(LEX *lc, BSR *bsr)
605 token = lex_get_token(lc, T_PINT32);
606 if (token == T_ERROR) {
609 stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME));
610 memset(stime, 0, sizeof(BSR_SESSTIME));
611 stime->sesstime = lc->pint32_val;
612 /* Add it to the end of the chain */
613 if (!bsr->sesstime) {
614 bsr->sesstime = stime;
616 /* Add to end of chain */
617 BSR_SESSTIME *bs = bsr->sesstime;
618 for ( ;bs->next; bs=bs->next)
622 token = lex_get_token(lc, T_ALL);
623 if (token != T_COMMA) {
631 static BSR *store_stream(LEX *lc, BSR *bsr)
637 token = lex_get_token(lc, T_INT32);
638 if (token == T_ERROR) {
641 stream = (BSR_STREAM *)malloc(sizeof(BSR_STREAM));
642 memset(stream, 0, sizeof(BSR_STREAM));
643 stream->stream = lc->int32_val;
644 /* Add it to the end of the chain */
646 bsr->stream = stream;
648 /* Add to end of chain */
649 BSR_STREAM *bs = bsr->stream;
650 for ( ;bs->next; bs=bs->next)
654 token = lex_get_token(lc, T_ALL);
655 if (token != T_COMMA) {
662 static BSR *store_slot(LEX *lc, BSR *bsr)
666 token = lex_get_token(lc, T_PINT32);
667 if (token == T_ERROR) {
671 Emsg1(M_ERROR,0, _("Slot %d in bsr at inappropriate place.\n"),
675 bsr->volume->Slot = lc->pint32_val;
680 static BSR *store_include(LEX *lc, BSR *bsr)
686 static BSR *store_exclude(LEX *lc, BSR *bsr)
692 void dump_volfile(BSR_VOLFILE *volfile)
695 Pmsg2(-1, _("VolFile : %u-%u\n"), volfile->sfile, volfile->efile);
696 dump_volfile(volfile->next);
700 void dump_volblock(BSR_VOLBLOCK *volblock)
703 Pmsg2(-1, _("VolBlock : %u-%u\n"), volblock->sblock, volblock->eblock);
704 dump_volblock(volblock->next);
709 void dump_findex(BSR_FINDEX *FileIndex)
712 if (FileIndex->findex == FileIndex->findex2) {
713 Pmsg1(-1, _("FileIndex : %u\n"), FileIndex->findex);
715 Pmsg2(-1, _("FileIndex : %u-%u\n"), FileIndex->findex, FileIndex->findex2);
717 dump_findex(FileIndex->next);
721 void dump_jobid(BSR_JOBID *jobid)
724 if (jobid->JobId == jobid->JobId2) {
725 Pmsg1(-1, _("JobId : %u\n"), jobid->JobId);
727 Pmsg2(-1, _("JobId : %u-%u\n"), jobid->JobId, jobid->JobId2);
729 dump_jobid(jobid->next);
733 void dump_sessid(BSR_SESSID *sessid)
736 if (sessid->sessid == sessid->sessid2) {
737 Pmsg1(-1, _("SessId : %u\n"), sessid->sessid);
739 Pmsg2(-1, _("SessId : %u-%u\n"), sessid->sessid, sessid->sessid2);
741 dump_sessid(sessid->next);
745 void dump_volume(BSR_VOLUME *volume)
748 Pmsg1(-1, _("VolumeName : %s\n"), volume->VolumeName);
749 Pmsg1(-1, _(" MediaType : %s\n"), volume->MediaType);
750 Pmsg1(-1, _(" Device : %s\n"), volume->device);
751 Pmsg1(-1, _(" Slot : %d\n"), volume->Slot);
752 dump_volume(volume->next);
757 void dump_client(BSR_CLIENT *client)
760 Pmsg1(-1, _("Client : %s\n"), client->ClientName);
761 dump_client(client->next);
765 void dump_job(BSR_JOB *job)
768 Pmsg1(-1, _("Job : %s\n"), job->Job);
773 void dump_sesstime(BSR_SESSTIME *sesstime)
776 Pmsg1(-1, _("SessTime : %u\n"), sesstime->sesstime);
777 dump_sesstime(sesstime->next);
782 void dump_bsr(BSR *bsr, bool recurse)
784 int save_debug = debug_level;
787 Pmsg0(-1, _("BSR is NULL\n"));
788 debug_level = save_debug;
791 Pmsg1(-1, _("Next : 0x%x\n"), bsr->next);
792 Pmsg1(-1, _("Root bsr : 0x%x\n"), bsr->root);
793 dump_volume(bsr->volume);
794 dump_sessid(bsr->sessid);
795 dump_sesstime(bsr->sesstime);
796 dump_volfile(bsr->volfile);
797 dump_volblock(bsr->volblock);
798 dump_client(bsr->client);
799 dump_jobid(bsr->JobId);
801 dump_findex(bsr->FileIndex);
803 Pmsg1(-1, _("count : %u\n"), bsr->count);
804 Pmsg1(-1, _("found : %u\n"), bsr->found);
807 Pmsg1(-1, _("done : %s\n"), bsr->done?_("yes"):_("no"));
808 Pmsg1(-1, _("positioning : %d\n"), bsr->use_positioning);
809 Pmsg1(-1, _("fast_reject : %d\n"), bsr->use_fast_rejection);
810 if (recurse && bsr->next) {
812 dump_bsr(bsr->next, true);
814 debug_level = save_debug;
819 /*********************************************************************
824 static void free_bsr_item(BSR *bsr)
827 free_bsr_item(bsr->next);
833 * Remove a single item from the bsr tree
835 void remove_bsr(BSR *bsr)
837 free_bsr_item((BSR *)bsr->volume);
838 free_bsr_item((BSR *)bsr->client);
839 free_bsr_item((BSR *)bsr->sessid);
840 free_bsr_item((BSR *)bsr->sesstime);
841 free_bsr_item((BSR *)bsr->volfile);
842 free_bsr_item((BSR *)bsr->volblock);
843 free_bsr_item((BSR *)bsr->JobId);
844 free_bsr_item((BSR *)bsr->job);
845 free_bsr_item((BSR *)bsr->FileIndex);
846 free_bsr_item((BSR *)bsr->JobType);
847 free_bsr_item((BSR *)bsr->JobLevel);
848 if (bsr->fileregex) {
849 bfree(bsr->fileregex);
851 if (bsr->fileregex_re) {
852 regfree(bsr->fileregex_re);
853 free(bsr->fileregex_re);
856 free_attr(bsr->attr);
859 bsr->next->prev = bsr->prev;
862 bsr->prev->next = bsr->next;
868 * Free all bsrs in chain
870 void free_bsr(BSR *bsr)
877 next_bsr = bsr->next;
878 /* Remove (free) current bsr */
880 /* Now get the next one */
884 /*****************************************************************
885 * Routines for handling volumes
887 static VOL_LIST *new_restore_volume()
890 vol = (VOL_LIST *)malloc(sizeof(VOL_LIST));
891 memset(vol, 0, sizeof(VOL_LIST));
896 * Add current volume to end of list, only if the Volume
897 * is not already in the list.
899 * returns: 1 if volume added
900 * 0 if volume already in list
902 static bool add_restore_volume(JCR *jcr, VOL_LIST *vol)
904 VOL_LIST *next = jcr->VolList;
906 /* Add volume to volume manager's read list */
907 add_read_volume(jcr, vol->VolumeName);
909 if (!next) { /* list empty ? */
910 jcr->VolList = vol; /* yes, add volume */
912 /* Loop through all but last */
913 for ( ; next->next; next=next->next) {
914 if (strcmp(vol->VolumeName, next->VolumeName) == 0) {
915 /* Save smallest start file */
916 if (vol->start_file < next->start_file) {
917 next->start_file = vol->start_file;
919 return false; /* already in list */
922 /* Check last volume in list */
923 if (strcmp(vol->VolumeName, next->VolumeName) == 0) {
924 if (vol->start_file < next->start_file) {
925 next->start_file = vol->start_file;
927 return false; /* already in list */
929 next->next = vol; /* add volume */
934 void free_restore_volume_list(JCR *jcr)
936 VOL_LIST *vol = jcr->VolList;
941 remove_read_volume(jcr, vol->VolumeName);
949 * Create a list of Volumes (and Slots and Start positions) to be
950 * used in the current restore job.
952 void create_restore_volume_list(JCR *jcr)
958 * Build a list of volumes to be processed
960 jcr->NumReadVolumes = 0;
961 jcr->CurReadVolume = 0;
964 if (!bsr->volume || !bsr->volume->VolumeName) {
967 for ( ; bsr; bsr=bsr->next) {
969 BSR_VOLFILE *volfile;
970 uint32_t sfile = UINT32_MAX;
972 /* Find minimum start file so that we can forward space to it */
973 for (volfile = bsr->volfile; volfile; volfile=volfile->next) {
974 if (volfile->sfile < sfile) {
975 sfile = volfile->sfile;
978 /* Now add volumes for this bsr */
979 for (bsrvol = bsr->volume; bsrvol; bsrvol=bsrvol->next) {
980 vol = new_restore_volume();
981 bstrncpy(vol->VolumeName, bsrvol->VolumeName, sizeof(vol->VolumeName));
982 bstrncpy(vol->MediaType, bsrvol->MediaType, sizeof(vol->MediaType));
983 bstrncpy(vol->device, bsrvol->device, sizeof(vol->device));
984 vol->Slot = bsrvol->Slot;
985 vol->start_file = sfile;
986 if (add_restore_volume(jcr, vol)) {
987 jcr->NumReadVolumes++;
988 Dmsg2(400, "Added volume=%s mediatype=%s\n", vol->VolumeName,
991 Dmsg1(400, "Duplicate volume %s\n", vol->VolumeName);
994 sfile = 0; /* start at beginning of second volume */
998 /* This is the old way -- deprecated */
999 for (p = jcr->dcr->VolumeName; p && *p; ) {
1000 n = strchr(p, '|'); /* volume name separator */
1002 *n++ = 0; /* Terminate name */
1004 vol = new_restore_volume();
1005 bstrncpy(vol->VolumeName, p, sizeof(vol->VolumeName));
1006 bstrncpy(vol->MediaType, jcr->dcr->media_type, sizeof(vol->MediaType));
1007 if (add_restore_volume(jcr, vol)) {
1008 jcr->NumReadVolumes++;