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 ammended 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;
115 Dmsg0(100, "No VOL1 label\n");
116 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
117 return VOL_NO_LABEL; /* No ANSI label */
121 /* Compare Volume Names allow special wild card */
122 if (VolName && *VolName && *VolName != '*') {
123 if (!same_label_names(VolName, &label[4])) {
125 char *q = dev->VolHdr.VolumeName;
126 for (int i=0; *p != ' ' && i < 6; i++) {
130 new_volume(dcr, dev->VolHdr.VolumeName);
131 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
132 Mmsg2(jcr->errmsg, "Wanted ANSI Volume \"%s\" got \"%s\"\n", VolName, dev->VolHdr.VolumeName);
133 return VOL_NAME_ERROR;
138 if (dev->label_type == B_IBM_LABEL) {
139 ebcdic_to_ascii(label, label, sizeof(label));
141 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
142 Dmsg0(100, "No HDR1 label\n");
143 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
144 return VOL_LABEL_ERROR;
146 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
147 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
149 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
150 dev->VolHdr.VolumeName);
151 return VOL_NAME_ERROR; /* Not a Bacula label */
155 if (dev->label_type == B_IBM_LABEL) {
156 ebcdic_to_ascii(label, label, sizeof(label));
158 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
159 Dmsg0(100, "No HDR2 label\n");
160 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
161 return VOL_LABEL_ERROR;
166 Dmsg0(100, "ANSI label OK\n");
169 if (dev->label_type == B_IBM_LABEL) {
170 ebcdic_to_ascii(label, label, sizeof(label));
172 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
173 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
174 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
175 return VOL_LABEL_ERROR;
180 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
181 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
182 return VOL_LABEL_ERROR;
186 * ANSI/IBM VOL1 label
187 * 80 characters blank filled
188 * Pos count Function What Bacula puts
190 * 4-9 6 Volume name Volume name
191 * 10-10 1 Access code
206 * ANSI/IBM HDR1 label
207 * 80 characters blank filled
208 * Pos count Function What Bacula puts
210 * 4-20 17 File name BACULA.DATA
211 * 21-26 6 Volume name Volume name
212 * 27-30 4 Vol seq num 0001
213 * 31-34 4 file num 0001
214 * 35-38 4 Generation 0001
215 * 39-40 2 Gen version 00
216 * 41-46 6 Create date bYYDDD yesterday
217 * 47-52 6 Expire date bYYDDD today
219 * 54-59 6 Block count 000000
220 * 60-72 13 Software name Bacula
223 * ANSI/IBM HDR2 label
224 * 80 characters blank filled
225 * Pos count Function What Bacula puts
227 * 4-4 1 Record format D (V if IBM) => variable
228 * 5-9 5 Block length 32000
229 * 10-14 5 Rec length 32000
236 * 38-38 1 Blocked flag
243 static const char *labels[] = {"HDR", "EOF", "EOV"};
246 * Write an ANSI or IBM 80 character tape label
247 * Type determines whether we are writing HDR, EOF, or EOV labels
248 * Assume we are positioned to write the labels
249 * Returns: true of OK
252 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
254 DEVICE *dev = dcr->dev;
256 char label[80]; /* tape label */
257 char date[20]; /* ansi date buffer */
259 int len, stat, label_type;
262 * If the Device requires a specific label type use it,
263 * otherwise, use the type requested by the Director
265 if (dcr->device->label_type != B_BACULA_LABEL) {
266 label_type = dcr->device->label_type; /* force label type */
268 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
271 switch (label_type) {
277 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
278 len = strlen(VolName);
280 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
284 if (type == ANSI_VOL_LABEL) {
285 ser_begin(label, sizeof(label));
286 ser_bytes("VOL1", 4);
287 ser_bytes(VolName, len);
288 /* Write VOL1 label */
289 if (label_type == B_IBM_LABEL) {
290 ascii_to_ebcdic(label, label, sizeof(label));
292 label[79] = '3'; /* ANSI label flag */
294 stat = write(dev->fd, label, sizeof(label));
295 if (stat != sizeof(label)) {
297 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
303 /* Now construct HDR1 label */
304 memset(label, ' ', sizeof(label));
305 ser_begin(label, sizeof(label));
306 ser_bytes(labels[type], 3);
308 ser_bytes("BACULA.DATA", 11); /* Filename field */
309 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
310 ser_bytes(VolName, len); /* write Vol Ser No. */
311 ser_begin(&label[27], sizeof(label)-27);
312 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
314 ser_bytes(ansi_date(now, date), 6); /* current date */
315 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
316 ser_bytes(" 000000Bacula ", 27);
317 /* Write HDR1 label */
318 if (label_type == B_IBM_LABEL) {
319 ascii_to_ebcdic(label, label, sizeof(label));
321 stat = write(dev->fd, label, sizeof(label));
322 if (stat != sizeof(label)) {
324 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
330 /* Now construct HDR2 label */
331 memset(label, ' ', sizeof(label));
332 ser_begin(label, sizeof(label));
333 ser_bytes(labels[type], 3);
334 ser_bytes("2D3200032000", 12);
335 /* Write HDR2 label */
336 if (label_type == B_IBM_LABEL) {
338 ascii_to_ebcdic(label, label, sizeof(label));
340 stat = write(dev->fd, label, sizeof(label));
341 if (stat != sizeof(label)) {
343 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
347 if (weof_dev(dev, 1) < 0) {
348 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
353 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
354 return false; /* should not get here */
358 /* Check a Bacula Volume name against an ANSI Volume name */
359 static bool same_label_names(char *bacula_name, char *ansi_name)
362 char *b = bacula_name;
363 /* Six characters max */
364 for (int i=0; i < 6; i++) {
370 /* ANSI labels are blank filled, Bacula's are zero terminated */
371 if (*a == ' ' && *b == 0) {
376 /* Reached 6 characters */
388 static char *ansi_date(time_t td, char *buf)
396 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);