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
17 version 2 as amended with additional clauses defined in the
18 file LICENSE in the main source directory.
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
23 the file LICENSE for additional details.
27 #include "bacula.h" /* pull in global headers */
28 #include "stored.h" /* pull in Storage Deamon headers */
30 /* Imported functions */
31 void ascii_to_ebcdic(char *dst, char *src, int count);
32 void ebcdic_to_ascii(char *dst, char *src, int count);
34 /* Forward referenced functions */
35 static char *ansi_date(time_t td, char *buf);
36 static bool same_label_names(char *bacula_name, char *ansi_name);
39 * We read an ANSI label and compare the Volume name. We require
40 * a VOL1 record of 80 characters followed by a HDR1 record containing
41 * BACULA.DATA in the filename field. We then read up to 3 more
42 * header records (they are not required) and an EOF, at which
46 * VOL_OK Volume name OK
47 * VOL_NO_LABEL No ANSI label on Volume
48 * VOL_IO_ERROR I/O error on read
49 * VOL_NAME_ERROR Wrong name in VOL1 record
50 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
53 int read_ansi_ibm_label(DCR *dcr)
55 DEVICE *dev = dcr->dev;
57 char label[80]; /* tape label */
59 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(100, "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(100, "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++;
91 dev->set_eot(); /* second eof, set eot bit */
92 Dmsg0(100, "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 */
96 dev->set_ateof(); /* set eof state */
100 case 0: /* Want VOL1 label */
102 if (strncmp("VOL1", label, 4) == 0) {
104 dev->label_type = B_ANSI_LABEL;
107 ebcdic_to_ascii(label, label, sizeof(label));
108 if (strncmp("VOL1", label, 4) == 0) {
110 dev->label_type = B_IBM_LABEL;
111 Dmsg0(100, "Found IBM label.\n");
116 Dmsg0(100, "No VOL1 label\n");
117 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
118 return VOL_NO_LABEL; /* No ANSI label */
122 /* Compare Volume Names allow special wild card */
123 if (VolName && *VolName && *VolName != '*') {
124 if (!same_label_names(VolName, &label[4])) {
126 char *q = dev->VolHdr.VolumeName;
127 for (int i=0; *p != ' ' && i < 6; i++) {
131 new_volume(dcr, dev->VolHdr.VolumeName);
132 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
133 Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolumeName);
134 return VOL_NAME_ERROR;
139 if (dev->label_type == B_IBM_LABEL) {
140 ebcdic_to_ascii(label, label, sizeof(label));
142 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
143 Dmsg0(100, "No HDR1 label\n");
144 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
145 return VOL_LABEL_ERROR;
147 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
148 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
150 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
151 dev->VolHdr.VolumeName);
152 return VOL_NAME_ERROR; /* Not a Bacula label */
156 if (dev->label_type == B_IBM_LABEL) {
157 ebcdic_to_ascii(label, label, sizeof(label));
159 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
160 Dmsg0(100, "No HDR2 label\n");
161 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
162 return VOL_LABEL_ERROR;
167 Dmsg0(100, "ANSI label OK\n");
170 if (dev->label_type == B_IBM_LABEL) {
171 ebcdic_to_ascii(label, label, sizeof(label));
173 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
174 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
175 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
176 return VOL_LABEL_ERROR;
181 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
182 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
183 return VOL_LABEL_ERROR;
187 * ANSI/IBM VOL1 label
188 * 80 characters blank filled
189 * Pos count Function What Bacula puts
191 * 4-9 6 Volume name Volume name
192 * 10-10 1 Access code
207 * ANSI/IBM HDR1 label
208 * 80 characters blank filled
209 * Pos count Function What Bacula puts
211 * 4-20 17 File name BACULA.DATA
212 * 21-26 6 Volume name Volume name
213 * 27-30 4 Vol seq num 0001
214 * 31-34 4 file num 0001
215 * 35-38 4 Generation 0001
216 * 39-40 2 Gen version 00
217 * 41-46 6 Create date bYYDDD yesterday
218 * 47-52 6 Expire date bYYDDD today
220 * 54-59 6 Block count 000000
221 * 60-72 13 Software name Bacula
224 * ANSI/IBM HDR2 label
225 * 80 characters blank filled
226 * Pos count Function What Bacula puts
228 * 4-4 1 Record format D (V if IBM) => variable
229 * 5-9 5 Block length 32000
230 * 10-14 5 Rec length 32000
237 * 38-38 1 Blocked flag
244 static const char *labels[] = {"HDR", "EOF", "EOV"};
247 * Write an ANSI or IBM 80 character tape label
248 * Type determines whether we are writing HDR, EOF, or EOV labels
249 * Assume we are positioned to write the labels
250 * Returns: true of OK
253 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
255 DEVICE *dev = dcr->dev;
257 char label[80]; /* tape label */
258 char date[20]; /* ansi date buffer */
260 int len, stat, label_type;
263 * If the Device requires a specific label type use it,
264 * otherwise, use the type requested by the Director
266 if (dcr->device->label_type != B_BACULA_LABEL) {
267 label_type = dcr->device->label_type; /* force label type */
269 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
272 switch (label_type) {
278 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
279 len = strlen(VolName);
281 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
285 if (type == ANSI_VOL_LABEL) {
286 ser_begin(label, sizeof(label));
287 ser_bytes("VOL1", 4);
288 ser_bytes(VolName, len);
289 /* Write VOL1 label */
290 if (label_type == B_IBM_LABEL) {
291 ascii_to_ebcdic(label, label, sizeof(label));
293 label[79] = '3'; /* ANSI label flag */
295 stat = write(dev->fd, label, sizeof(label));
296 if (stat != sizeof(label)) {
298 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
304 /* Now construct HDR1 label */
305 memset(label, ' ', sizeof(label));
306 ser_begin(label, sizeof(label));
307 ser_bytes(labels[type], 3);
309 ser_bytes("BACULA.DATA", 11); /* Filename field */
310 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
311 ser_bytes(VolName, len); /* write Vol Ser No. */
312 ser_begin(&label[27], sizeof(label)-27);
313 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
315 ser_bytes(ansi_date(now, date), 6); /* current date */
316 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
317 ser_bytes(" 000000Bacula ", 27);
318 /* Write HDR1 label */
319 if (label_type == B_IBM_LABEL) {
320 ascii_to_ebcdic(label, label, sizeof(label));
322 stat = write(dev->fd, label, sizeof(label));
323 if (stat != sizeof(label)) {
325 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
331 /* Now construct HDR2 label */
332 memset(label, ' ', sizeof(label));
333 ser_begin(label, sizeof(label));
334 ser_bytes(labels[type], 3);
335 ser_bytes("2D3200032000", 12);
336 /* Write HDR2 label */
337 if (label_type == B_IBM_LABEL) {
339 ascii_to_ebcdic(label, label, sizeof(label));
341 stat = write(dev->fd, label, sizeof(label));
342 if (stat != sizeof(label)) {
344 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
348 if (weof_dev(dev, 1) < 0) {
349 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
354 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
355 return false; /* should not get here */
359 /* Check a Bacula Volume name against an ANSI Volume name */
360 static bool same_label_names(char *bacula_name, char *ansi_name)
363 char *b = bacula_name;
364 /* Six characters max */
365 for (int i=0; i < 6; i++) {
371 /* ANSI labels are blank filled, Bacula's are zero terminated */
372 if (*a == ' ' && *b == 0) {
377 /* Reached 6 characters */
389 static char *ansi_date(time_t td, char *buf)
397 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);