+/*
+ Bacula(R) - The Network Backup Solution
+
+ Copyright (C) 2000-2016 Kern Sibbald
+
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
+*/
/*
*
* ansi_label.c routines to handle ANSI (and perhaps one day IBM)
*
* Kern Sibbald, MMV
*
- *
- *
- * Version $Id$
- */
-/*
- Copyright (C) 2005-2006 Kern Sibbald
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- version 2 as amended with additional clauses defined in the
- file LICENSE in the main source directory.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- the file LICENSE for additional details.
-
*/
#include "bacula.h" /* pull in global headers */
/*
* We read an ANSI label and compare the Volume name. We require
* a VOL1 record of 80 characters followed by a HDR1 record containing
- * BACULA.DATA in the filename field. We then read up to 3 more
+ * BACULA.DATA in the filename field. We then read up to 3 more
* header records (they are not required) and an EOF, at which
* point, all is good.
*
* VOL_IO_ERROR I/O error on read
* VOL_NAME_ERROR Wrong name in VOL1 record
* VOL_LABEL_ERROR Probably an ANSI label, but something wrong
- *
- */
-int read_ansi_ibm_label(DCR *dcr)
+ *
+ */
+int read_ansi_ibm_label(DCR *dcr)
{
- DEVICE *dev = dcr->dev;
+ DEVICE * volatile dev = dcr->dev;
JCR *jcr = dcr->jcr;
char label[80]; /* tape label */
int stat, i;
/* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
for (i=0; i < 6; i++) {
do {
- stat = read(dev->fd, label, sizeof(label));
+ stat = dev->read(label, sizeof(label));
} while (stat == -1 && errno == EINTR);
if (stat < 0) {
berrno be;
dev->clrerror(-1);
- Dmsg1(100, "Read device got: ERR=%s\n", be.strerror());
+ Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror());
Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
- dev->dev_name, be.strerror());
+ dev->dev_name, be.bstrerror());
Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
dev->VolCatInfo.VolCatErrors++;
return VOL_IO_ERROR;
if (strncmp("VOL1", label, 4) == 0) {
ok = true;
dev->label_type = B_ANSI_LABEL;
+ Dmsg0(100, "Got ANSI VOL1 label\n");
} else {
/* Try EBCDIC */
ebcdic_to_ascii(label, label, sizeof(label));
ok = true;;
dev->label_type = B_IBM_LABEL;
Dmsg0(100, "Found IBM label.\n");
+ Dmsg0(100, "Got IBM VOL1 label\n");
}
- }
+ }
}
if (!ok) {
Dmsg0(100, "No VOL1 label\n");
/* Compare Volume Names allow special wild card */
- if (VolName && *VolName && *VolName != '*') {
+ if (VolName && *VolName && *VolName != '*') {
if (!same_label_names(VolName, &label[4])) {
char *p = &label[4];
- char *q;
+ char *q;
free_volume(dev);
/* Store new Volume name */
*q++ = *p++;
}
*q = 0;
- new_volume(dcr, dev->VolHdr.VolumeName);
+ Dmsg0(100, "Call reserve_volume\n");
+ /* ***FIXME*** why is this reserve_volume() needed???? KES */
+ reserve_volume(dcr, dev->VolHdr.VolumeName);
+ dev = dcr->dev; /* may have changed in reserve_volume */
Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
return VOL_NAME_ERROR;
dev->VolHdr.VolumeName);
return VOL_NAME_ERROR; /* Not a Bacula label */
}
+ Dmsg0(100, "Got HDR1 label\n");
break;
case 2:
if (dev->label_type == B_IBM_LABEL) {
Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
return VOL_LABEL_ERROR;
}
+ Dmsg0(100, "Got ANSI HDR2 label\n");
break;
default:
if (stat == 0) {
Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
return VOL_LABEL_ERROR;
}
+ Dmsg0(100, "Got HDR label\n");
break;
}
}
Dmsg0(100, "Too many records in ANSI/IBM label.\n");
Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
return VOL_LABEL_ERROR;
-}
+}
/*
* ANSI/IBM VOL1 label
* Pos count Function What Bacula puts
* 0-3 4 "VOL1" VOL1
* 4-9 6 Volume name Volume name
- * 10-10 1 Access code
+ * 10-10 1 Access code
* 11-36 26 Unused
*
* ANSI
* 5-9 5 Block length 32000
* 10-14 5 Rec length 32000
* 15-15 1 Density
- * 16-16 1 Continued
+ * 16-16 1 Continued
* 17-33 17 Job
* 34-35 2 Recording
* 36-36 1 cr/lf ctl
* 50-51 2 offset
* 52-79 28 reserved
- */
+ */
static const char *labels[] = {"HDR", "EOF", "EOV"};
{
DEVICE *dev = dcr->dev;
JCR *jcr = dcr->jcr;
+ char ansi_volname[7]; /* 6 char + \0 */
char label[80]; /* tape label */
char date[20]; /* ansi date buffer */
time_t now;
VolName);
return false;
}
+ /* ANSI labels have 6 characters, and are padded with spaces
+ * 'vol1\0' => 'vol1 \0'
+ */
+ strcpy(ansi_volname, VolName);
+ for(int i=len; i < 6; i++) {
+ ansi_volname[i]=' ';
+ }
+ ansi_volname[6]='\0'; /* only for debug */
+
if (type == ANSI_VOL_LABEL) {
ser_begin(label, sizeof(label));
ser_bytes("VOL1", 4);
- ser_bytes(VolName, len);
+ ser_bytes(ansi_volname, 6);
/* Write VOL1 label */
if (label_type == B_IBM_LABEL) {
ascii_to_ebcdic(label, label, sizeof(label));
} else {
label[79] = '3'; /* ANSI label flag */
}
- stat = write(dev->fd, label, sizeof(label));
+ stat = dev->write(label, sizeof(label));
if (stat != sizeof(label)) {
berrno be;
- Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
- be.strerror());
+ Jmsg3(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. Wanted size=%d got=%d ERR=%s\n"),
+ sizeof(label), stat, be.bstrerror());
return false;
}
}
ser_bytes("1", 1);
ser_bytes("BACULA.DATA", 11); /* Filename field */
ser_begin(&label[21], sizeof(label)-21); /* fileset field */
- ser_bytes(VolName, len); /* write Vol Ser No. */
+ ser_bytes(ansi_volname, 6); /* write Vol Ser No. */
ser_begin(&label[27], sizeof(label)-27);
ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
now = time(NULL);
* This could come at the end of a tape, ignore
* EOT errors.
*/
- stat = write(dev->fd, label, sizeof(label));
+ stat = dev->write(label, sizeof(label));
if (stat != sizeof(label)) {
berrno be;
if (stat == -1) {
}
if (dev->dev_errno != ENOSPC) {
Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
- be.strerror());
+ be.bstrerror());
return false;
}
} else {
label[4] = 'V';
ascii_to_ebcdic(label, label, sizeof(label));
}
- stat = write(dev->fd, label, sizeof(label));
+ stat = dev->write(label, sizeof(label));
if (stat != sizeof(label)) {
berrno be;
if (stat == -1) {
}
if (dev->dev_errno != ENOSPC) {
Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
- be.strerror());
+ be.bstrerror());
return false;
}
dev->weof(1);