3 * ansi_label.c routines to handle ANSI (and perhaps one day IBM)
13 Copyright (C) 2005-2006 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 = tape_read(dev->fd, label, sizeof(label));
78 } while (stat == -1 && errno == EINTR);
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])) {
129 /* Store new Volume name */
130 q = dev->VolHdr.VolumeName;
131 for (int i=0; *p != ' ' && i < 6; i++) {
135 new_volume(dcr, dev->VolHdr.VolumeName);
136 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
137 Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
138 return VOL_NAME_ERROR;
143 if (dev->label_type == B_IBM_LABEL) {
144 ebcdic_to_ascii(label, label, sizeof(label));
146 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
147 Dmsg0(100, "No HDR1 label\n");
148 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
149 return VOL_LABEL_ERROR;
151 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
152 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
154 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
155 dev->VolHdr.VolumeName);
156 return VOL_NAME_ERROR; /* Not a Bacula label */
160 if (dev->label_type == B_IBM_LABEL) {
161 ebcdic_to_ascii(label, label, sizeof(label));
163 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
164 Dmsg0(100, "No HDR2 label\n");
165 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
166 return VOL_LABEL_ERROR;
171 Dmsg0(100, "ANSI label OK\n");
174 if (dev->label_type == B_IBM_LABEL) {
175 ebcdic_to_ascii(label, label, sizeof(label));
177 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
178 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
179 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
180 return VOL_LABEL_ERROR;
185 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
186 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
187 return VOL_LABEL_ERROR;
191 * ANSI/IBM VOL1 label
192 * 80 characters blank filled
193 * Pos count Function What Bacula puts
195 * 4-9 6 Volume name Volume name
196 * 10-10 1 Access code
211 * ANSI/IBM HDR1 label
212 * 80 characters blank filled
213 * Pos count Function What Bacula puts
215 * 4-20 17 File name BACULA.DATA
216 * 21-26 6 Volume name Volume name
217 * 27-30 4 Vol seq num 0001
218 * 31-34 4 file num 0001
219 * 35-38 4 Generation 0001
220 * 39-40 2 Gen version 00
221 * 41-46 6 Create date bYYDDD yesterday
222 * 47-52 6 Expire date bYYDDD today
224 * 54-59 6 Block count 000000
225 * 60-72 13 Software name Bacula
228 * ANSI/IBM HDR2 label
229 * 80 characters blank filled
230 * Pos count Function What Bacula puts
232 * 4-4 1 Record format D (V if IBM) => variable
233 * 5-9 5 Block length 32000
234 * 10-14 5 Rec length 32000
241 * 38-38 1 Blocked flag
248 static const char *labels[] = {"HDR", "EOF", "EOV"};
251 * Write an ANSI or IBM 80 character tape label
252 * Type determines whether we are writing HDR, EOF, or EOV labels
253 * Assume we are positioned to write the labels
254 * Returns: true of OK
257 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
259 DEVICE *dev = dcr->dev;
261 char label[80]; /* tape label */
262 char date[20]; /* ansi date buffer */
264 int len, stat, label_type;
267 * If the Device requires a specific label type use it,
268 * otherwise, use the type requested by the Director
270 if (dcr->device->label_type != B_BACULA_LABEL) {
271 label_type = dcr->device->label_type; /* force label type */
273 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
276 switch (label_type) {
282 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
283 len = strlen(VolName);
285 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
289 if (type == ANSI_VOL_LABEL) {
290 ser_begin(label, sizeof(label));
291 ser_bytes("VOL1", 4);
292 ser_bytes(VolName, len);
293 /* Write VOL1 label */
294 if (label_type == B_IBM_LABEL) {
295 ascii_to_ebcdic(label, label, sizeof(label));
297 label[79] = '3'; /* ANSI label flag */
299 stat = tape_write(dev->fd, label, sizeof(label));
300 if (stat != sizeof(label)) {
302 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
308 /* Now construct HDR1 label */
309 memset(label, ' ', sizeof(label));
310 ser_begin(label, sizeof(label));
311 ser_bytes(labels[type], 3);
313 ser_bytes("BACULA.DATA", 11); /* Filename field */
314 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
315 ser_bytes(VolName, len); /* write Vol Ser No. */
316 ser_begin(&label[27], sizeof(label)-27);
317 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
319 ser_bytes(ansi_date(now, date), 6); /* current date */
320 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
321 ser_bytes(" 000000Bacula ", 27);
322 /* Write HDR1 label */
323 if (label_type == B_IBM_LABEL) {
324 ascii_to_ebcdic(label, label, sizeof(label));
328 * This could come at the end of a tape, ignore
331 stat = tape_write(dev->fd, label, sizeof(label));
332 if (stat != sizeof(label)) {
336 if (dev->dev_errno == 0) {
337 dev->dev_errno = ENOSPC; /* out of space */
339 if (dev->dev_errno != ENOSPC) {
340 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
345 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
350 /* Now construct HDR2 label */
351 memset(label, ' ', sizeof(label));
352 ser_begin(label, sizeof(label));
353 ser_bytes(labels[type], 3);
354 ser_bytes("2D3200032000", 12);
355 /* Write HDR2 label */
356 if (label_type == B_IBM_LABEL) {
358 ascii_to_ebcdic(label, label, sizeof(label));
360 stat = tape_write(dev->fd, label, sizeof(label));
361 if (stat != sizeof(label)) {
365 if (dev->dev_errno == 0) {
366 dev->dev_errno = ENOSPC; /* out of space */
368 if (dev->dev_errno != ENOSPC) {
369 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
376 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
381 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
386 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
387 return false; /* should not get here */
391 /* Check a Bacula Volume name against an ANSI Volume name */
392 static bool same_label_names(char *bacula_name, char *ansi_name)
395 char *b = bacula_name;
396 /* Six characters max */
397 for (int i=0; i < 6; i++) {
403 /* ANSI labels are blank filled, Bacula's are zero terminated */
404 if (*a == ' ' && *b == 0) {
409 /* Reached 6 characters */
421 static char *ansi_date(time_t td, char *buf)
429 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);