3 * ansi_label.c routines to handle ANSI (and perhaps one day IBM)
13 Copyright (C) 2005 Kern Sibbald
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of
18 the License, or (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but 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
26 License along with this program; if not, write to the Free
27 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
32 #include "bacula.h" /* pull in global headers */
33 #include "stored.h" /* pull in Storage Deamon headers */
35 /* Forward referenced functions */
36 static char *ansi_date(time_t td, char *buf);
37 static bool same_label_names(char *bacula_name, char *ansi_name);
40 * We read an ANSI label and compare the Volume name. We require
41 * a VOL1 record of 80 characters followed by a HDR1 record containing
42 * BACULA.DATA in the filename field. We then read up to 3 more
43 * header records (they are not required) and an EOF, at which
47 * VOL_OK Volume name OK
48 * VOL_NO_LABEL No ANSI label on Volume
49 * VOL_IO_ERROR I/O error on read
50 * VOL_NAME_ERROR Wrong name in VOL1 record
51 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
54 int read_ansi_ibm_label(DCR *dcr)
56 DEVICE *dev = dcr->dev;
58 char label[80]; /* tape label */
60 char *VolName = dcr->VolumeName;
63 * Read VOL1, HDR1, HDR2 labels, but ignore the data
64 * If tape read the following EOF mark, on disk do
67 Dmsg0(000, "Read ansi label.\n");
68 if (!dev->is_tape()) {
72 dev->label_type = B_BACULA_LABEL; /* assume Bacula label */
74 /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
75 for (i=0; i < 6; i++) {
77 stat = read(dev->fd, label, sizeof(label));
78 } while (stat == -1 && errno == EINTR);
81 clrerror_dev(dev, -1);
82 Dmsg1(000, "Read device got: ERR=%s\n", be.strerror());
83 Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
84 dev->dev_name, be.strerror());
85 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
86 dev->VolCatInfo.VolCatErrors++;
92 Dmsg0(000, "EOM on ANSI label\n");
93 Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
94 return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */
100 case 0: /* Want VOL1 label */
101 if (stat != 80 || strncmp("VOL1", label, 4) != 0) {
102 Dmsg0(000, "No VOL1 label\n");
103 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI label.\n"));
104 return VOL_NO_LABEL; /* No ANSI label */
107 dev->label_type = B_ANSI_LABEL;
109 /* Compare Volume Names allow special wild card */
110 if (VolName && *VolName && *VolName != '*') {
111 if (!same_label_names(VolName, &label[4])) {
113 char *q = dev->VolHdr.VolName;
114 for (int i=0; *p != ' ' && i < 6; i++) {
118 Dmsg2(000, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolName);
119 Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolName);
120 return VOL_NAME_ERROR;
125 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
126 Dmsg0(000, "No HDR1 label\n");
127 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
128 return VOL_LABEL_ERROR;
130 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
131 Dmsg1(000, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
133 Mmsg1(jcr->errmsg, _("ANSI Volume \"%s\" does not belong to Bacula.\n"),
134 dev->VolHdr.VolName);
135 return VOL_NAME_ERROR; /* Not a Bacula label */
139 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
140 Dmsg0(000, "No HDR2 label\n");
141 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI label.\n"));
142 return VOL_LABEL_ERROR;
147 Dmsg0(000, "ANSI label OK\n");
150 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
151 Dmsg0(000, "Unknown or bad ANSI label record.\n");
152 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI label record.\n"));
153 return VOL_LABEL_ERROR;
158 Dmsg0(000, "Too many records in ANSI label.\n");
159 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI label.\n"));
160 return VOL_LABEL_ERROR;
164 * Write an ANSI or IBM 80 character tape label
165 * Assume we are positioned at the beginning of the tape.
166 * Returns: true of OK
169 bool write_ansi_ibm_label(DCR *dcr, const char *VolName)
171 DEVICE *dev = dcr->dev;
173 char label[80]; /* tape label */
174 char date[20]; /* ansi date buffer */
176 int len, stat, label_type;
179 * If the Device requires a specific label type use it,
180 * otherwise, use the type requested by the Director
182 if (dcr->device->label_type != B_BACULA_LABEL) {
183 label_type = dcr->device->label_type; /* force label type */
185 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
188 switch (label_type) {
194 Dmsg1(000, "Write ANSI label type=%d\n", label_type);
195 len = strlen(VolName);
197 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
201 memset(label, ' ', sizeof(label));
202 ser_begin(label, sizeof(label));
203 ser_bytes("VOL1", 4);
204 ser_bytes(VolName, len);
205 label[79] = '3'; /* ANSI label flag */
206 /* Write VOL1 label */
207 stat = write(dev->fd, label, sizeof(label));
208 if (stat != sizeof(label)) {
210 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
214 /* Now construct HDR1 label */
215 ser_begin(label, sizeof(label));
216 ser_bytes("HDR1", 4);
217 ser_bytes("BACULA.DATA", 11); /* Filename field */
218 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
219 ser_bytes(VolName, len); /* write Vol Ser No. */
220 ser_begin(&label[27], sizeof(label)-27);
221 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
223 ser_bytes(ansi_date(now, date), 6); /* current date */
224 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
225 ser_bytes(" 000000Bacula ", 27);
226 /* Write HDR1 label */
227 stat = write(dev->fd, label, sizeof(label));
228 if (stat != sizeof(label)) {
230 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
234 /* Now construct HDR2 label */
235 memset(label, ' ', sizeof(label));
236 ser_begin(label, sizeof(label));
237 ser_bytes("HDR2F3200032000", 15);
238 /* Write HDR1 label */
239 stat = write(dev->fd, label, sizeof(label));
240 if (stat != sizeof(label)) {
242 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
246 if (weof_dev(dev, 1) < 0) {
247 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
252 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
253 return false; /* should not get here */
257 /* Check a Bacula Volume name against an ANSI Volume name */
258 static bool same_label_names(char *bacula_name, char *ansi_name)
261 char *b = bacula_name;
262 /* Six characters max */
263 for (int i=0; i < 6; i++) {
269 /* ANSI labels are blank filled, Bacula's are zero terminated */
270 if (*a == ' ' && *b == 0) {
275 /* Reached 6 characters */
284 static char *ansi_date(time_t td, char *buf)
292 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);