3 * ansi_label.c routines to handle ANSI (and perhaps one day IBM)
13 Bacula® - The Network Backup Solution
15 Copyright (C) 2005-2006 Free Software Foundation Europe e.V.
17 The main author of Bacula is Kern Sibbald, with contributions from
18 many others, a complete list can be found in the file AUTHORS.
19 This program is Free Software; you can redistribute it and/or
20 modify it under the terms of version two of the GNU General Public
21 License as published by the Free Software Foundation and included
24 This program is distributed in the hope that it will be useful, but
25 WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 Bacula® is a registered trademark of John Walker.
35 The licensor of Bacula is the Free Software Foundation Europe
36 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
37 Switzerland, email:ftf@fsfeurope.org.
40 #include "bacula.h" /* pull in global headers */
41 #include "stored.h" /* pull in Storage Deamon headers */
43 /* Imported functions */
44 void ascii_to_ebcdic(char *dst, char *src, int count);
45 void ebcdic_to_ascii(char *dst, char *src, int count);
47 /* Forward referenced functions */
48 static char *ansi_date(time_t td, char *buf);
49 static bool same_label_names(char *bacula_name, char *ansi_name);
52 * We read an ANSI label and compare the Volume name. We require
53 * a VOL1 record of 80 characters followed by a HDR1 record containing
54 * BACULA.DATA in the filename field. We then read up to 3 more
55 * header records (they are not required) and an EOF, at which
59 * VOL_OK Volume name OK
60 * VOL_NO_LABEL No ANSI label on Volume
61 * VOL_IO_ERROR I/O error on read
62 * VOL_NAME_ERROR Wrong name in VOL1 record
63 * VOL_LABEL_ERROR Probably an ANSI label, but something wrong
66 int read_ansi_ibm_label(DCR *dcr)
68 DEVICE *dev = dcr->dev;
70 char label[80]; /* tape label */
72 char *VolName = dcr->VolumeName;
76 * Read VOL1, HDR1, HDR2 labels, but ignore the data
77 * If tape read the following EOF mark, on disk do
80 Dmsg0(100, "Read ansi label.\n");
81 if (!dev->is_tape()) {
85 dev->label_type = B_BACULA_LABEL; /* assume Bacula label */
87 /* Read a maximum of 5 records VOL1, HDR1, ... HDR4 */
88 for (i=0; i < 6; i++) {
90 stat = dev->read(label, sizeof(label));
91 } while (stat == -1 && errno == EINTR);
95 Dmsg1(100, "Read device got: ERR=%s\n", be.bstrerror());
96 Mmsg2(jcr->errmsg, _("Read error on device %s in ANSI label. ERR=%s\n"),
97 dev->dev_name, be.bstrerror());
98 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
99 dev->VolCatInfo.VolCatErrors++;
104 dev->set_eot(); /* second eof, set eot bit */
105 Dmsg0(100, "EOM on ANSI label\n");
106 Mmsg0(jcr->errmsg, _("Insane! End of tape while reading ANSI label.\n"));
107 return VOL_LABEL_ERROR; /* at EOM this shouldn't happen */
109 dev->set_ateof(); /* set eof state */
113 case 0: /* Want VOL1 label */
115 if (strncmp("VOL1", label, 4) == 0) {
117 dev->label_type = B_ANSI_LABEL;
120 ebcdic_to_ascii(label, label, sizeof(label));
121 if (strncmp("VOL1", label, 4) == 0) {
123 dev->label_type = B_IBM_LABEL;
124 Dmsg0(100, "Found IBM label.\n");
129 Dmsg0(100, "No VOL1 label\n");
130 Mmsg0(jcr->errmsg, _("No VOL1 label while reading ANSI/IBM label.\n"));
131 return VOL_NO_LABEL; /* No ANSI label */
135 /* Compare Volume Names allow special wild card */
136 if (VolName && *VolName && *VolName != '*') {
137 if (!same_label_names(VolName, &label[4])) {
142 /* Store new Volume name */
143 q = dev->VolHdr.VolumeName;
144 for (int i=0; *p != ' ' && i < 6; i++) {
148 reserve_volume(dcr, dev->VolHdr.VolumeName);
149 Dmsg2(100, "Wanted ANSI Vol %s got %6s\n", VolName, dev->VolHdr.VolumeName);
150 Mmsg2(jcr->errmsg, _("Wanted ANSI Volume \"%s\" got \"%s\"\n"), VolName, dev->VolHdr.VolumeName);
151 return VOL_NAME_ERROR;
156 if (dev->label_type == B_IBM_LABEL) {
157 ebcdic_to_ascii(label, label, sizeof(label));
159 if (stat != 80 || strncmp("HDR1", label, 4) != 0) {
160 Dmsg0(100, "No HDR1 label\n");
161 Mmsg0(jcr->errmsg, _("No HDR1 label while reading ANSI label.\n"));
162 return VOL_LABEL_ERROR;
164 if (strncmp("BACULA.DATA", &label[4], 11) != 0) {
165 Dmsg1(100, "HD1 not Bacula label. Wanted BACULA.DATA got %11s\n",
167 Mmsg1(jcr->errmsg, _("ANSI/IBM Volume \"%s\" does not belong to Bacula.\n"),
168 dev->VolHdr.VolumeName);
169 return VOL_NAME_ERROR; /* Not a Bacula label */
173 if (dev->label_type == B_IBM_LABEL) {
174 ebcdic_to_ascii(label, label, sizeof(label));
176 if (stat != 80 || strncmp("HDR2", label, 4) != 0) {
177 Dmsg0(100, "No HDR2 label\n");
178 Mmsg0(jcr->errmsg, _("No HDR2 label while reading ANSI/IBM label.\n"));
179 return VOL_LABEL_ERROR;
184 Dmsg0(100, "ANSI label OK\n");
187 if (dev->label_type == B_IBM_LABEL) {
188 ebcdic_to_ascii(label, label, sizeof(label));
190 if (stat != 80 || strncmp("HDR", label, 3) != 0) {
191 Dmsg0(100, "Unknown or bad ANSI/IBM label record.\n");
192 Mmsg0(jcr->errmsg, _("Unknown or bad ANSI/IBM label record.\n"));
193 return VOL_LABEL_ERROR;
198 Dmsg0(100, "Too many records in ANSI/IBM label.\n");
199 Mmsg0(jcr->errmsg, _("Too many records in while reading ANSI/IBM label.\n"));
200 return VOL_LABEL_ERROR;
204 * ANSI/IBM VOL1 label
205 * 80 characters blank filled
206 * Pos count Function What Bacula puts
208 * 4-9 6 Volume name Volume name
209 * 10-10 1 Access code
224 * ANSI/IBM HDR1 label
225 * 80 characters blank filled
226 * Pos count Function What Bacula puts
228 * 4-20 17 File name BACULA.DATA
229 * 21-26 6 Volume name Volume name
230 * 27-30 4 Vol seq num 0001
231 * 31-34 4 file num 0001
232 * 35-38 4 Generation 0001
233 * 39-40 2 Gen version 00
234 * 41-46 6 Create date bYYDDD yesterday
235 * 47-52 6 Expire date bYYDDD today
237 * 54-59 6 Block count 000000
238 * 60-72 13 Software name Bacula
241 * ANSI/IBM HDR2 label
242 * 80 characters blank filled
243 * Pos count Function What Bacula puts
245 * 4-4 1 Record format D (V if IBM) => variable
246 * 5-9 5 Block length 32000
247 * 10-14 5 Rec length 32000
254 * 38-38 1 Blocked flag
261 static const char *labels[] = {"HDR", "EOF", "EOV"};
264 * Write an ANSI or IBM 80 character tape label
265 * Type determines whether we are writing HDR, EOF, or EOV labels
266 * Assume we are positioned to write the labels
267 * Returns: true of OK
270 bool write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName)
272 DEVICE *dev = dcr->dev;
274 char label[80]; /* tape label */
275 char date[20]; /* ansi date buffer */
277 int len, stat, label_type;
280 * If the Device requires a specific label type use it,
281 * otherwise, use the type requested by the Director
283 if (dcr->device->label_type != B_BACULA_LABEL) {
284 label_type = dcr->device->label_type; /* force label type */
286 label_type = dcr->VolCatInfo.LabelType; /* accept Dir type */
289 switch (label_type) {
295 Dmsg1(100, "Write ANSI label type=%d\n", label_type);
296 len = strlen(VolName);
298 Jmsg1(jcr, M_FATAL, 0, _("ANSI Volume label name \"%s\" longer than 6 chars.\n"),
302 if (type == ANSI_VOL_LABEL) {
303 ser_begin(label, sizeof(label));
304 ser_bytes("VOL1", 4);
305 ser_bytes(VolName, len);
306 /* Write VOL1 label */
307 if (label_type == B_IBM_LABEL) {
308 ascii_to_ebcdic(label, label, sizeof(label));
310 label[79] = '3'; /* ANSI label flag */
312 stat = dev->write(label, sizeof(label));
313 if (stat != sizeof(label)) {
315 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI VOL1 label. ERR=%s\n"),
321 /* Now construct HDR1 label */
322 memset(label, ' ', sizeof(label));
323 ser_begin(label, sizeof(label));
324 ser_bytes(labels[type], 3);
326 ser_bytes("BACULA.DATA", 11); /* Filename field */
327 ser_begin(&label[21], sizeof(label)-21); /* fileset field */
328 ser_bytes(VolName, len); /* write Vol Ser No. */
329 ser_begin(&label[27], sizeof(label)-27);
330 ser_bytes("00010001000100", 14); /* File section, File seq no, Generation no */
332 ser_bytes(ansi_date(now, date), 6); /* current date */
333 ser_bytes(ansi_date(now - 24 * 3600, date), 6); /* created yesterday */
334 ser_bytes(" 000000Bacula ", 27);
335 /* Write HDR1 label */
336 if (label_type == B_IBM_LABEL) {
337 ascii_to_ebcdic(label, label, sizeof(label));
341 * This could come at the end of a tape, ignore
344 stat = dev->write(label, sizeof(label));
345 if (stat != sizeof(label)) {
349 if (dev->dev_errno == 0) {
350 dev->dev_errno = ENOSPC; /* out of space */
352 if (dev->dev_errno != ENOSPC) {
353 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
358 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
363 /* Now construct HDR2 label */
364 memset(label, ' ', sizeof(label));
365 ser_begin(label, sizeof(label));
366 ser_bytes(labels[type], 3);
367 ser_bytes("2D3200032000", 12);
368 /* Write HDR2 label */
369 if (label_type == B_IBM_LABEL) {
371 ascii_to_ebcdic(label, label, sizeof(label));
373 stat = dev->write(label, sizeof(label));
374 if (stat != sizeof(label)) {
378 if (dev->dev_errno == 0) {
379 dev->dev_errno = ENOSPC; /* out of space */
381 if (dev->dev_errno != ENOSPC) {
382 Jmsg1(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label. ERR=%s\n"),
389 Jmsg(jcr, M_FATAL, 0, _("Could not write ANSI HDR1 label.\n"));
394 Jmsg(jcr, M_FATAL, 0, _("Error writing EOF to tape. ERR=%s"), dev->errmsg);
399 Jmsg0(jcr, M_ABORT, 0, _("write_ansi_ibm_label called for non-ANSI/IBM type\n"));
400 return false; /* should not get here */
404 /* Check a Bacula Volume name against an ANSI Volume name */
405 static bool same_label_names(char *bacula_name, char *ansi_name)
408 char *b = bacula_name;
409 /* Six characters max */
410 for (int i=0; i < 6; i++) {
416 /* ANSI labels are blank filled, Bacula's are zero terminated */
417 if (*a == ' ' && *b == 0) {
422 /* Reached 6 characters */
434 static char *ansi_date(time_t td, char *buf)
442 bsnprintf(buf, 10, " %05d ", 1000 * (tm->tm_year + 1900 - 2000) + tm->tm_yday);