-
-/*
- * 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;
- int stat;
-
- Dmsg1(100, "LabelType=%d\n", dcr->VolCatInfo.LabelType);
- switch (dcr->VolCatInfo.LabelType) {
- case B_BACULA_LABEL:
- return true;
- case B_ANSI_LABEL:
- case B_IBM_LABEL:
- ser_declare;
- Dmsg0(100, "Write ansi label.\n");
- len = strlen(VolName);
- if (len > 6) {
- len = 6; /* max len ANSI label */
- }
- 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);
- len = strlen(VolName);
- if (len > 17) {
- len = 17; /* Max filename len */
- }
- ser_bytes(VolName, len); /* stick Volume name in Filename field */
- if (len > 6) {
- len = 6;
- }
- ser_begin(&label[21], sizeof(label)-21);
- 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 retry, stat, i, num_rec;
-
- if (dcr->VolCatInfo.LabelType == B_BACULA_LABEL) {
- return VOL_OK;
- }
- /*
- * Read VOL1, HDR1, HDR2 labels, but ignore the data
- * If tape read the following EOF mark, on disk do
- * not read.
- */
- Dmsg0(100, "Read ansi label.\n");
- if (dev->is_tape()) {
- num_rec = 4;
- } else {
- num_rec = 3;
- }
- for (i=0; i < num_rec; i++) {
- retry = 0;
- do {
- stat = read(dev->fd, label, sizeof(label));
- if (retry == 1) {
- dev->VolCatInfo.VolCatErrors++;
- }
- } while (stat == -1 && (errno == EINTR || errno == EIO) && retry++ < 11);
- if (stat < 0) {
- berrno be;
- clrerror_dev(dev, -1);
- Dmsg1(200, "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);
- if (dev->at_eof()) { /* EOF just seen? */
- dev->state |= ST_EOT; /* yes, error => EOT */
- }
- return VOL_IO_ERROR;
- }
- }
- 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;
-}