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 /* Imported functions */
36 void ascii_to_ebcdic(char *dst, char *src, int count);
37 void ebcdic_to_ascii(char *dst, char *src, int count);
39 /* Forward referenced functions */
40 static char *ansi_date(time_t td, char *buf);
41 static bool same_label_names(char *bacula_name, char *ansi_name);
44 * We read an ANSI label and compare the Volume name. We require
45 * a VOL1 record of 80 characters followed by a HDR1 record containing
46 * BACULA.DATA in the filename field. We then read up to 3 more
47 * header records (they are not required) and an EOF, at which
51 * VOL_OK Volume name OK
52 * VOL_NO_LABEL No ANSI label on Volume
53 * VOL_IO_ERROR I/O error on read
54 * VOL_NAME_ERROR Wrong name in VOL1 record
55 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
58 int read_ansi_ibm_label(DCR *dcr)
60 DEVICE *dev = dcr->dev;
62 char label[80]; /* tape label */
64 char *VolName = dcr->VolumeName;
68 * Read VOL1, HDR1, HDR2 labels, but ignore the data
69 * If tape read the following EOF mark, on disk do
72 Dmsg0(100, "Read ansi label.\n");
73 if (!dev->is_tape()) {
77 dev->label_type = B_BACULA_LABEL; /* assume Bacula label */
79 /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
80 for (i=0; i < 6; i++) {
82 stat = read(dev->fd, label, sizeof(label));
83 } while (stat == -1 && errno == EINTR);
86 clrerror_dev(dev, -1);
87 Dmsg1(100, "Read device got: ERR=%s\n", be.strerror());
88 Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
89 dev->dev_name, be.strerror());
90 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
91 dev->VolCatInfo.VolCatErrors++;
97 Dmsg0(100, "EOM on ANSI label\n");
98 Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
99 return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */
105 case 0: /* Want VOL1 label */
107 if (strncmp("VOL1", label, 4) == 0) {
109 dev->label_type = B_ANSI_LABEL;
112 ebcdic_to_ascii(label, label, sizeof(label));
113 if (strncmp("VOL1", label, 4) == 0) {
115 dev->label_type = B_IBM_LABEL;
120 Dmsg0(100, "No VOL1 label\n");
121 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
122 return VOL_NO_LABEL; /* No ANSI label */
126 /* Compare Volume Names allow special wild card */
127 if (VolName && *VolName && *VolName != '*') {
128 if (!same_label_names(VolName, &label[4])) {
130 char *q = dev->VolHdr.VolName;
131 for (int i=0; *p != ' ' && i < 6; i++) {
135 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolName);
136 Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolName);
137 return VOL_NAME_ERROR;
142 if (dev->label_type == B_IBM_LABEL) {
143 ebcdic_to_ascii(label, label, sizeof(label));
145 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
146 Dmsg0(100, "No HDR1 label\n");
147 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
148 return VOL_LABEL_ERROR;
150 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
151 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
153 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
154 dev->VolHdr.VolName);
155 return VOL_NAME_ERROR; /* Not a Bacula label */
159 if (dev->label_type == B_IBM_LABEL) {
160 ebcdic_to_ascii(label, label, sizeof(label));
162 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
163 Dmsg0(100, "No HDR2 label\n");
164 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
165 return VOL_LABEL_ERROR;
170 Dmsg0(100, "ANSI label OK\n");
173 if (dev->label_type == B_IBM_LABEL) {
174 ebcdic_to_ascii(label, label, sizeof(label));
176 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
177 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
178 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
179 return VOL_LABEL_ERROR;
184 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
185 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
186 return VOL_LABEL_ERROR;
190 * ANSI/IBM VOL1 label
191 * 80 characters blank filled
192 * Pos count Function What Bacula puts
194 * 4-9 6 Volume name Volume name
195 * 10-10 1 Access code
210 * ANSI/IBM HDR1 label
211 * 80 characters blank filled
212 * Pos count Function What Bacula puts
214 * 4-20 17 File name BACULA.DATA
215 * 21-26 6 Volume name Volume name
216 * 27-30 4 Vol seq num 0001
217 * 31-34 4 file num 0001
218 * 35-38 4 Generation 0001
219 * 39-40 2 Gen version 00
220 * 41-46 6 Create date bYYDDD yesterday
221 * 47-52 6 Expire date bYYDDD today
223 * 54-59 6 Block count 000000
224 * 60-72 13 Software name Bacula
227 * ANSI/IBM HDR2 label
228 * 80 characters blank filled
229 * Pos count Function What Bacula puts
231 * 4-4 1 Record format D (V if IBM) => variable
232 * 5-9 5 Block length 32000
233 * 10-14 5 Rec length 32000
240 * 38-38 1 Blocked flag
247 static const char *labels[] = {"HDR", "EOF", "EOV"};
250 * Write an ANSI or IBM 80 character tape label
251 * Type determines whether we are writing HDR, EOF, or EOV labels
252 * Assume we are positioned to write the labels
253 * Returns: true of OK
256 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
258 DEVICE *dev = dcr->dev;
260 char label[80]; /* tape label */
261 char date[20]; /* ansi date buffer */
263 int len, stat, label_type;
266 * If the Device requires a specific label type use it,
267 * otherwise, use the type requested by the Director
269 if (dcr->device->label_type != B_BACULA_LABEL) {
270 label_type = dcr->device->label_type; /* force label type */
272 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
275 switch (label_type) {
281 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
282 len = strlen(VolName);
284 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
288 if (type == ANSI_VOL_LABEL) {
289 ser_begin(label, sizeof(label));
290 ser_bytes("VOL1", 4);
291 ser_bytes(VolName, len);
292 /* Write VOL1 label */
293 if (label_type == B_IBM_LABEL) {
294 ascii_to_ebcdic(label, label, sizeof(label));
296 label[79] = '3'; /* ANSI label flag */
298 stat = write(dev->fd, label, sizeof(label));
299 if (stat != sizeof(label)) {
301 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
307 /* Now construct HDR1 label */
308 memset(label, ' ', sizeof(label));
309 ser_begin(label, sizeof(label));
310 ser_bytes(labels[type], 3);
312 ser_bytes("BACULA.DATA", 11); /* Filename field */
313 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
314 ser_bytes(VolName, len); /* write Vol Ser No. */
315 ser_begin(&label[27], sizeof(label)-27);
316 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
318 ser_bytes(ansi_date(now, date), 6); /* current date */
319 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
320 ser_bytes(" 000000Bacula ", 27);
321 /* Write HDR1 label */
322 if (label_type == B_IBM_LABEL) {
323 ascii_to_ebcdic(label, label, sizeof(label));
325 stat = write(dev->fd, label, sizeof(label));
326 if (stat != sizeof(label)) {
328 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
334 /* Now construct HDR2 label */
335 memset(label, ' ', sizeof(label));
336 ser_begin(label, sizeof(label));
337 ser_bytes(labels[type], 3);
338 ser_bytes("2D3200032000", 12);
339 /* Write HDR2 label */
340 if (label_type == B_IBM_LABEL) {
342 ascii_to_ebcdic(label, label, sizeof(label));
344 stat = write(dev->fd, label, sizeof(label));
345 if (stat != sizeof(label)) {
347 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
351 if (weof_dev(dev, 1) < 0) {
352 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
357 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
358 return false; /* should not get here */
362 /* Check a Bacula Volume name against an ANSI Volume name */
363 static bool same_label_names(char *bacula_name, char *ansi_name)
366 char *b = bacula_name;
367 /* Six characters max */
368 for (int i=0; i < 6; i++) {
374 /* ANSI labels are blank filled, Bacula's are zero terminated */
375 if (*a == ' ' && *b == 0) {
380 /* Reached 6 characters */
392 static char *ansi_date(time_t td, char *buf)
400 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);