-
-/*
- * Write an ANSI or IBM 80 character tape label
- * Assume we are positioned at the beginning of the tape.
- * Returns: true of OK
- * false if error
- */
-bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
-{
- DEVICE *dev = dcr->dev;
- JCR *jcr = dcr->jcr;
- char label[80]; /* tape label */
- char date[20]; /* ansi date buffer */
- time_t now;
- int len, stat, label_type;
-
- /*
- * If the Device requires a specific label type use it,
- * otherwise, use the type requested by the Director
- */
- if (dcr->device->label_type != B_BACULA_LABEL) {
- label_type = dcr->device->label_type; /* force label type */
- } else {
- label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
- }
-
- switch (label_type) {
- case B_BACULA_LABEL:
- return true;
- case B_ANSI_LABEL:
- case B_IBM_LABEL:
- ser_declare;
- Dmsg1(000, "Write ANSI label type=%d\n", label_type);
- len = strlen(VolName);
- if (len > 6) {
- Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
- VolName);
- return false;
- }
- memset(label, ' ', sizeof(label));
- ser_begin(label, sizeof(label));
- ser_bytes("VOL1", 4);
- ser_bytes(VolName, len);
- label[79] = '3'; /* ANSI label flag */
- /* Write VOL1 label */
- stat = write(dev->fd, 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());
- return false;
- }
- /* Now construct HDR1 label */
- ser_begin(label, sizeof(label));
- ser_bytes("HDR1", 4);
- 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_begin(&label[27], sizeof(label)-27);
- ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
- now = time(NULL);
- ser_bytes(ansi_date(now, date), 6); /* current date */
- ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
- ser_bytes(" 000000Bacula ", 27);
- /* Write HDR1 label */
- stat = write(dev->fd, label, sizeof(label));
- if (stat != sizeof(label)) {
- berrno be;
- Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
- be.strerror());
- return false;
- }
- /* Now construct HDR2 label */
- memset(label, ' ', sizeof(label));
- ser_begin(label, sizeof(label));
- ser_bytes("HDR2F3200032000", 15);
- /* Write HDR1 label */
- stat = write(dev->fd, label, sizeof(label));
- if (stat != sizeof(label)) {
- berrno be;
- Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
- be.strerror());
- return false;
- }
- if (weof_dev(dev, 1) < 0) {
- Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
- return false;
- }
- return true;
- default:
- Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
- return false; /* should not get here */
- }
-}
-
-static int read_ansi_ibm_label(DCR *dcr)
-{
- DEVICE *dev = dcr->dev;
- JCR *jcr = dcr->jcr;
- char label[80]; /* tape label */
- int stat, i, num_rec;
-
- /*
- * Read VOL1, HDR1, HDR2 labels, but ignore the data
- * If tape read the following EOF mark, on disk do
- * not read.
- */
- Dmsg0(000, "Read ansi label.\n");
- if (dev->is_tape()) {
- num_rec = 4;
- } else {
- num_rec = 3;
- }
- for (i=0; i < num_rec; i++) {
- do {
- stat = read(dev->fd, label, sizeof(label));
- } while (stat == -1 && errno == EINTR);
- if (stat < 0) {
- berrno be;
- clrerror_dev(dev, -1);
- Dmsg1(000, "Read device got: ERR=%s\n", be.strerror());
- Mmsg2(dev->errmsg, _("Read error on device %s in ANSI/IBM label. ERR=%s\n"),
- dev->dev_name, be.strerror());
- Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
- dev->VolCatInfo.VolCatErrors++;
- return VOL_IO_ERROR;
- }
- if (stat == 0) {
- if (dev->at_eof()) {
- dev->state |= ST_EOT;
- return VOL_NO_LABEL;
- } else {
- dev->state |= ST_EOF;
- }
- }
- switch (i) {
- case 0: /* Want VOL1 label */
- if (stat != 80 || strncmp("VOL1", label, 4) != 0) {
- Dmsg0(000, "No VOL1 label\n");
- return VOL_NO_LABEL;
- }
- break;
- case 1:
- if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
- Dmsg0(000, "No HDR1 label\n");
- return VOL_NO_LABEL;
- }
- if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
- Dmsg0(000, "HD1 not Bacula label\n");
- return VOL_NAME_ERROR;
- }
- break;
- case 2:
- if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
- Dmsg0(000, "No HDR2 label\n");
- return VOL_NO_LABEL;
- }
- break;
- case 3: /* Should get EOF here */
- if (stat != 0) {
- Dmsg0(000, "No EOF\n");
- return VOL_IO_ERROR;
- }
- break;
- }
- }
- /* ***FIXME*** add detection of IBM labels */
- dev->label_type = B_ANSI_LABEL;
- Dmsg0(000, "ANSI label OK\n");
- return VOL_OK;
-}
-
-
-static char *ansi_date(time_t td, char *buf)
-{
- struct tm *tm;
-
- if (td == 0) {
- td = time(NULL);
- }
- tm = gmtime(&td);
- bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);
- return buf;
-}